Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort
1 Neues in Java 7
2 Threads und nebenläufige Programmierung
3 Datenstrukturen und Algorithmen
4 Raum und Zeit
5 Dateien, Verzeichnisse und Dateizugriffe
6 Datenströme
7 Die eXtensible Markup Language (XML)
8 Dateiformate
9 Grafische Oberflächen mit Swing
10 Grafikprogrammierung
11 Netzwerkprogrammierung
12 Verteilte Programmierung mit RMI
13 RESTful und SOAP Web-Services
14 JavaServer Pages und Servlets
15 Applets
16 Datenbankmanagement mit JDBC
17 Technologien für die Infrastruktur
18 Reflection und Annotationen
19 Dynamische Übersetzung und Skriptsprachen
20 Logging und Monitoring
21 Java Native Interface (JNI)
22 Sicherheitskonzepte
23 Dienstprogramme für die Java-Umgebung
Stichwort
Download: - openbook, ca. 21,3 MB
Buch bestellen
Ihre Meinung?
<< zurück | Galileo Computing / <openbook> / Java 7 - Mehr als eine Insel | vor >>
Java 7 - Mehr als eine Insel von Christian Ullenboom Das Handbuch zu den Java SE-Bibliotheken
Java 7 - Mehr als eine Insel Galileo Computing 1433 S., 2012, geb. 49,90 Euro, ISBN 978-3-8362-1507-7 |
| 5 Dateien, Verzeichnisse und Dateizugriffe
|  | 5.1 Datei und Verzeichnis
|  |  | 5.1.1 Dateien und Verzeichnisse mit der Klasse File
|  |  | 5.1.2 Verzeichnis oder Datei? Existiert es?
|  |  | 5.1.3 Verzeichnis- und Dateieigenschaften/-attribute
|  |  | 5.1.4 Umbenennen und Verzeichnisse anlegen
|  |  | 5.1.5 Verzeichnisse auflisten und Dateien filtern
|  |  | 5.1.6 Dateien berühren, neue Dateien anlegen, temporäre Dateien
|  |  | 5.1.7 Dateien und Verzeichnisse löschen
|  |  | 5.1.8 Verzeichnisse nach Dateien iterativ durchsuchen *
|  |  | 5.1.9 Wurzelverzeichnis, Laufwerksnamen, Plattenspeicher *
|  |  | 5.1.10 URL-, URI- und Path-Objekte aus einem File-Objekt ableiten *
|  |  | 5.1.11 Mit Locking Dateien sperren *
|  |  | 5.1.12 Sicherheitsprüfung *
|  |  | 5.1.13 Zugriff auf SMB-Server mit jCIFS *
|  | 5.2 Dateien mit wahlfreiem Zugriff
|  |  | 5.2.1 Ein RandomAccessFile zum Lesen und Schreiben öffnen
|  |  | 5.2.2 Aus dem RandomAccessFile lesen
|  |  | 5.2.3 Schreiben mit RandomAccessFile
|  |  | 5.2.4 Die Länge des RandomAccessFile
|  |  | 5.2.5 Hin und her in der Datei
|  | 5.3 Dateisysteme unter NIO.2
|  |  | 5.3.1 FileSystem und Path
|  |  | 5.3.2 Die Utility-Klasse Files
|  |  | 5.3.3 Dateien kopieren und verschieben
|  |  | 5.3.4 Dateiattribute *
|  |  | 5.3.5 Neue Dateien, Verzeichnisse, symbolische Verknüpfungen anlegen und löschen
|  |  | 5.3.6 MIME-Typen testen *
|  |  | 5.3.7 Verzeichnislistings (DirectoryStream) und Filter *
|  |  | 5.3.8 Rekursive Abläufe des Verzeichnisbaums (FileVisitor) *
|  |  | 5.3.9 Dateisysteme und Dateisystemattribute *
|  |  | 5.3.10 Verzeichnisse im Dateisystem überwachen *
|  | 5.4 Wahlfreier Zugriff mit SeekableByteChannel und ByteBuffer *
|  |  | 5.4.1 SeekableByteChannel
|  |  | 5.4.2 ByteBuffer
|  |  | 5.4.3 Beispiel mit Path + SeekableByteChannel + ByteBuffer
|  |  | 5.4.4 FileChannel
|  | 5.5 Zum Weiterlesen
## 5.4 Wahlfreier Zugriff mit SeekableByteChannel und ByteBuffer * Für den wahlfreien Zugriff auf Bytes in Dateien bietet Java seit Version 1.0 die Klasse RandomAccessFile. Unter Java 7 ist die Klasse nun nicht mehr nötig, und genau genommen ist sie es auch schon seit Java 1.4 nicht mehr, denn in Java 1.4 wurde das erste NIO-Paket eingeführt – und mit ihm sogenannte Channel-Klassen, die eine offene Verbindung mit einem Datenkanal repräsentieren. Neu in Java 7 ist die Verbindung von Path und einem besonderen Channel für die wahlfreie Ein-/Ausgabe, dem SeekableByteChannel, der ebenfalls in Java 7 eingeführt wurde. Gegenüber dem 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. ### 5.4.1 SeekableByteChannel 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. ### 5.4.2 ByteBuffer 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 b) 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 direkte ByteBuffer sind wie byte[]-Felder, also Java-Objekte, die auf dem Heap Platz einnehmen. Bei einem direkten ByteBuffer versucht Java, einen Speicherbereich vom Betriebssystem zu bekommen. Während die nicht direkten ByteBuffer und byte-Arrays auf dem Heap leben und dem normalen GC 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. ### 5.4.3 Beispiel mit Path + SeekableByteChannel + ByteBuffer 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 5.36: com/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() aus dem byte[] der Strings ein nicht direkter Buffer angelegt wird, den write() dann in den Kanal schreibt. Abbildung 5.14: Die 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. ### 5.4.4 FileChannel 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.[44](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() 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 5.37: com/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 Strom-Klassen realisiert. Sie werden im folgenden Kapitel vorgestellt. ### Ihr Kommentar Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen. >> Zum Feedback-Formular
<< zurück | <top> | vor >>
Zum Katalog
Java 7 – Mehr als eine Insel Jetzt bestellen
Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen? Ihre Meinung
Buchempfehlungen
| Java und XML
| Einstieg in Eclipse 3.7
| Android 3
| NetBeans Platform 7
| Java ist auch eine Insel
| Apps entwickeln für Android 4
| Java 7
Shopping
Versandkostenfrei bestellen in Deutschland und Österreich Info

Copyright © Galileo Press 2012
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das 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.

[Galileo Computing]
Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de