Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.
 
Inhaltsverzeichnis
Vorwort
1 Neues in Java 8 und Java 7
2 Fortgeschrittene String-Verarbeitung
3 Threads und nebenläufige Programmierung
4 Datenstrukturen und Algorithmen
5 Raum und Zeit
6 Dateien, Verzeichnisse und Dateizugriffe
7 Datenströme
8 Die eXtensible Markup Language (XML)
9 Dateiformate
10 Grafische Oberflächen mit Swing
11 Grafikprogrammierung
12 JavaFX
13 Netzwerkprogrammierung
14 Verteilte Programmierung mit RMI
15 RESTful und SOAP-Web-Services
16 Technologien für die Infrastruktur
17 Typen, Reflection und Annotationen
18 Dynamische Übersetzung und Skriptsprachen
19 Logging und Monitoring
20 Sicherheitskonzepte
21 Datenbankmanagement mit JDBC
22 Java Native Interface (JNI)
23 Dienstprogramme für die Java-Umgebung
Stichwortverzeichnis

Jetzt Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Java SE 8 Standard-Bibliothek von Christian Ullenboom
Das Handbuch für Java-Entwickler
Buch: Java SE 8 Standard-Bibliothek

Java SE 8 Standard-Bibliothek
Pfeil 6 Dateien, Verzeichnisse und Dateizugriffe
Pfeil 6.1 Alte und neue Welt in java.io und java.nio
Pfeil 6.1.1 java.io-Paket mit File-Klasse
Pfeil 6.1.2 NIO.2 und java.nio-Paket
Pfeil 6.2 Dateisysteme und Pfade
Pfeil 6.2.1 FileSystem und Path
Pfeil 6.2.2 Die Utility-Klasse Files
Pfeil 6.2.3 Dateien kopieren und verschieben
Pfeil 6.2.4 Dateiattribute *
Pfeil 6.2.5 Neue Dateien, Verzeichnisse, symbolische Verknüpfungen anlegen und löschen
Pfeil 6.2.6 MIME-Typen herausfinden *
Pfeil 6.2.7 Verzeichnislistings (DirectoryStream/Stream) und Filter *
Pfeil 6.2.8 Rekursives Ablaufen des Verzeichnisbaums *
Pfeil 6.2.9 Rekursiv nach Dateien/Ordnern suchen mit Files.find(…) *
Pfeil 6.2.10 Dateisysteme und Dateisystemattribute *
Pfeil 6.2.11 Verzeichnisse im Dateisystem überwachen *
Pfeil 6.3 Datei- und Verzeichnis-Operationen mit der Klasse File
Pfeil 6.3.1 Dateien und Verzeichnisse mit der Klasse File
Pfeil 6.3.2 Verzeichnis oder Datei? Existiert es?
Pfeil 6.3.3 Verzeichnis- und Dateieigenschaften/-attribute
Pfeil 6.3.4 Umbenennen und Verzeichnisse anlegen
Pfeil 6.3.5 Verzeichnisse auflisten und Dateien filtern
Pfeil 6.3.6 Dateien berühren, neue Dateien anlegen, temporäre Dateien
Pfeil 6.3.7 Dateien und Verzeichnisse löschen
Pfeil 6.3.8 Wurzelverzeichnis, Laufwerksnamen, Plattenspeicher *
Pfeil 6.3.9 URL-, URI- und Path-Objekte aus einem File-Objekt ableiten *
Pfeil 6.3.10 Mit Locking Dateien sperren *
Pfeil 6.3.11 Sicherheitsprüfung *
Pfeil 6.3.12 Zugriff auf SMB-Server mit jCIFS *
Pfeil 6.4 Dateien mit wahlfreiem Zugriff
Pfeil 6.4.1 Ein RandomAccessFile zum Lesen und Schreiben öffnen
Pfeil 6.4.2 Aus dem RandomAccessFile lesen
Pfeil 6.4.3 Schreiben mit RandomAccessFile
Pfeil 6.4.4 Die Länge des RandomAccessFile
Pfeil 6.4.5 Hin und her in der Datei
Pfeil 6.5 Wahlfreier Zugriff mit SeekableByteChannel und ByteBuffer *
Pfeil 6.5.1 SeekableByteChannel
Pfeil 6.5.2 ByteBuffer
Pfeil 6.5.3 Beispiel mit Path + SeekableByteChannel + ByteBuffer
Pfeil 6.5.4 FileChannel
Pfeil 6.6 Zum Weiterlesen
 
Zum Seitenanfang

6.5Wahlfreier Zugriff mit SeekableByteChannel und ByteBuffer * Zur vorigen ÜberschriftZur nächsten Überschrift

Für den wahlfreien Zugriff auf Bytes in Dateien bietet Java seit Version 1.0 die Klasse RandomAccessFile. Eine moderne Alternative für wahlfreie Ein-/Ausgabe bietet SeekableByteChannel. Der Typ steht für einen so genannten Channel; diese repräsentieren eine offene Verbindung mit einem Datenkanal. Mit einem Path ist so ein SeekableByteChannel leicht erfragt, und dann lässt sich ein Dateizeiger positionieren und lassen sich Daten lesen und schreiben. Gegenüber RandomAccessFile ist wegen einer hardwarenahen Implementierung eine bessere Geschwindigkeit möglich, sonst bietet ein SeekableByteChannel keine großartigen Vorzüge, er ist sogar etwas umständlicher in der Nutzung.

 
Zum Seitenanfang

6.5.1SeekableByteChannel Zur vorigen ÜberschriftZur nächsten Überschrift

Der SeekableByteChannel deklariert Operationen zum Lesen und Schreiben von Daten und zur Positionierung des Dateizeigers.

interface java.nio.channels.SeekableByteChannel
extends ByteChannel
  • int read(ByteBuffer dst) throws IOException

  • int write(ByteBuffer src) throws IOException

  • long size() throws IOException

  • long position() throws IOException

  • SeekableByteChannel position(long newPosition) throws IOException

  • SeekableByteChannel truncate(long size) throws IOException

Die Methoden close() und isOpen() kommen aus Channel hinzu.

Es fällt auf, und das ist einer der großen Unterschiede zu RandomAccessFile, dass SeekableByteChannel kein byte-Feld oder einzelne Bytes liest oder schreibt, sondern mit ByteBuffer einen ganz eigenen Typ erwartet.

 
Zum Seitenanfang

6.5.2ByteBuffer Zur vorigen ÜberschriftZur nächsten Überschrift

Ein ByteBuffer ist einem Byte-Feld sehr ähnlich; seine maximale Größe wird vorher festgelegt und kann später nicht dynamisch wachsen. Ist ein ByteBuffer angelegt, so können über einen Index die einzelnen Bytes gelesen und geschrieben werden, zum Beispiel mit byte get() oder put(byte) relativ zur letzten Position – oder mit byte get(int index) und put(int index, byte b) absolut. Der wirkliche Unterschied ist aber, dass Java zwei verschiedene Arten von ByteBuffer-Implementierungen bietet (ByteBuffer ist eine abstrakte Klasse):

  • Nicht direkteByteBuffer sind wie byte[]-Felder, also Java-Objekte, die auf dem Heap Platz einnehmen.

  • Bei einem direktenByteBuffer versucht Java, einen Speicherbereich vom Betriebssystem zu bekommen. Während die nicht direkten ByteBuffer und byte-Arrays auf dem Heap leben und der normalen automatischen Speicherbereinigung unterworfen sind, sollten die direkten ByteBuffer vom Betriebssystem verwaltet werden. Im Idealfall sind dadurch hohe Ein-/Ausgabegeschwindigkeiten möglich, denn mit direkten ByteBuffern kann sich das Betriebssystem Kopieroperationen zwischen nativen internen Puffern und Java-Puffern sparen.

Die Methoden auf direkten oder nicht direkten ByteBuffern sind identisch. Insbesondere gilt das für das Speichern aller Pufferzustände: die Position, ein Limit und eine Kapazität. Diesen Eigenschaften wollen wir aber in der Insel nicht nachgehen.

 
Zum Seitenanfang

6.5.3Beispiel mit Path + SeekableByteChannel + ByteBuffer Zur vorigen ÜberschriftZur nächsten Überschrift

Das folgende Beispiel fasst alles zusammen: Von einem Path wird über newByteChannel ein SeekableByteChannel erfragt. Anschließend leiten wir aus einer Zeichenkette über das byte[] einen nicht direkten ByteBuffer ab und schreiben diesen in den SeekableByteChannel, sodass später die Datei Kurt Cobain.txt einen ASCII-Text enthält.

Listing 6.34com/tutego/insel/nio2/SeekableByteChannelDemo.java, main()

try ( SeekableByteChannel raf = Files.newByteChannel( Paths.get("Kurt Cobain.txt"),
StandardOpenOption.CREATE,
StandardOpenOption.WRITE ) ) {
String s = "Drugs are bad for you. ";
ByteBuffer byteBuffer = ByteBuffer.wrap( s.getBytes() );
raf.write( byteBuffer );
raf.write( ByteBuffer.wrap( "They will f*ck you up.".getBytes() ) );
raf.position( 34 );
raf.write( ByteBuffer.wrap( new byte[]{'u'} ) );
}

Das Beispiel zeigt, dass mit ByteBuffer.wrap(byte[]) aus dem Byte-Feld des Strings ein nicht direkter Buffer angelegt wird, den write(ByteBuffer) dann in den Kanal schreibt.

Die Datei im Hex-Editor

Abbildung 6.11Die Datei im Hex-Editor

Nur zum Testen schreiben wir ASCII-Zeichen, was aber im »echten Leben« eher nicht der Fall sein wird, denn wir müssen hier die korrekten Zeichenkodierungen beachten. Auch für sequenzielle Schreiboperationen ist der SeekableByteChannel eher weniger komfortabel – dennoch ist der Einsatz von Kanälen nicht per se falsch. Im nächsten Kapitel werden die Ströme vorgestellt, mit denen das Schreiben, insbesondere von Textdokumenten, viel einfacher wird.

 
Zum Seitenanfang

6.5.4FileChannel Zur vorigen ÜberschriftZur nächsten Überschrift

Die Schnittstelle SeekableByteChannel gibt Operationen an, um die aktuelle Position auszulesen und den Positionszeiger neu zu setzen und über ByteBuffer Bytes und Bytefolgen zu lesen und zu schreiben. SeekableByteChannel ist dabei nicht an Dateien gebunden und enthält keine Informationen zu Dateipfaden oder sonstigen tiefer liegenden Schichten. Und da Path grundsätzlich ein Pfad auf alles Mögliche sein kann, etwa auf ein BLOB in der Datenbank, liefert newByteChannel(…) eine Rückgabe mindestens von Typ SeekableByteChannel – und damit erst einmal keine Möglichkeiten, um dateispezifische Operationen vorzunehmen.

Wird allerdings newByteChannel(…) auf einem Pfad aufgerufen, der eine Datei vom Dateisystem repräsentiert, so ist die Rückgabe nicht einfach nur ein SeekableByteChannel, sondern der Untertyp FileChannel.[ 80 ](Den Typ FileChannel gibt es in Java schon länger, nämlich seit Java 1.4. Und vor Java 7 lieferten die Methoden getChannel() von FileInputStream, FileOutputStream und RandomAccessFile den FileChannel.) Ein Typecast ist daher möglich:

Path p = Paths.get( "Kurt Cobain.txt" );
FileChannel channel = (FileChannel) Files.newByteChannel( p, options );

Da FileChannel die Schnittstelle SeekableByteChannel implementiert, bietet natürlich FileChannel alle Methoden zum Lesen, Schreiben und Positionieren. Zusätzlich bietet FileChannel aber Methoden, die explizit an Dateien gebunden sind. Drei Methoden fallen sofort auf:

  • lock(…): Sperrt die Datei (oder Dateiteile) für andere, soweit es das Betriebssystem unterstützt.

  • force(…): Updates werden sofort materialisiert, das heißt auf das Dateisystem übertragen.

  • map(…): Blendet die Datei, oder einen Teil der Datei, in den Speicher ein.

Die Methode map(FileChannel.MapMode, long, long) ist besonders interessant. Damit kann ein FileChannel auf einen ByteBuffer abgebildet werden, sodass unsere Lese-/Schreiboperationen auf dem ByteBuffer direkt aus der Datei kommen oder direkt in die Datei gehen. Das Betriebssystem versucht sein Bestes, die Operationen zu optimieren und geeignete Blöcke der Datei in den Speicher zu laden. Java und das Betriebssystem kooperieren also eng, um die Operationen so schnell wie möglich und mit wenigen Kopieroperationen zwischen den internen Puffern des Dateisystems und den Java-Puffern durchzuführen.

Das folgende Beispiel bezieht im ersten Schritt über newByteChannel(…) den FileChannel. Anschließend bildet die Methode map(…) die gesamte Datei auf einen MappedByteBuffer ab, der ein ByteBuffer ist, wie wir ihn im letzten Beispiel schon kennengelernt haben. Wir könnten nun Methoden auf dem ByteBuffer aufrufen und die Bytes auslesen, doch hier gehen wir etwas anders vor: Die Bytes des ByteBuffer konvertiert ein CharsetDecoder von ASCII in Java-Unicode; das Ergebnis ist ein CharBuffer. Den CharBuffer laufen wir ab und geben die Zeichen auf der Konsole aus:

Listing 6.35com/tutego/insel/nio2/FileChannelDemo.java, main()

Path p = Paths.get( "Kurt Cobain.txt" );
try ( FileChannel fileChannel = (FileChannel) Files.newByteChannel( p,
StandardOpenOption.READ ) ) {
ByteBuffer byteBuffer = fileChannel.map( FileChannel.MapMode.READ_ONLY, 0,
fileChannel.size() );

CharsetDecoder decoder = StandardCharsets.ISO_8859_1.newDecoder();
CharBuffer charBuffer = decoder.decode( byteBuffer );

while ( charBuffer.hasRemaining() )
System.out.print( charBuffer.get() );
}

Beim FileChannel gilt das Gleiche wie beim SeekableByteChannel. Sequenzieller Lese- oder Schreibzugriff wird am einfachsten über die Stromklassen realisiert. Sie werden im folgenden Kapitel vorgestellt.

 


Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

<< zurück
 Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Java SE 8 Standard-Bibliothek Java SE 8 Standard-Bibliothek
Jetzt Buch bestellen

 Buchempfehlungen
Zum Rheinwerk-Shop: Java ist auch eine Insel
Java ist auch eine Insel


Zum Rheinwerk-Shop: Professionell entwickeln mit Java EE 8
Professionell entwickeln mit Java EE 8


Zum Rheinwerk-Shop: Besser coden
Besser coden


Zum Rheinwerk-Shop: Entwurfsmuster
Entwurfsmuster


Zum Rheinwerk-Shop: IT-Projektmanagement
IT-Projektmanagement


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo

 
 


Copyright © Rheinwerk Verlag GmbH 2018
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

 
Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern