Java Input/Output System (IO)

Werbung
Java Input/Output System (IO)
Ziel: Schreiben und Lesen von Daten auf sequentielle Medien.
Paket: java.io.
ab Java 1.4 auch java.nio, hier nicht beru cksichtigt.
Trennung in 2 Welten:
- Byteorientierte IO (InputStreams, OutputStreams). Bytes sind 8bit-Werte ohne Interpretation des Inhaltes.
- Zeichenorientierte IO (Readers, Writers). Zeichen sind 16-bitUnicode-Zeichen.
Grundstruktur ist in beiden Fallen gleich. Sequentielle Datenstrome,
die u ber Filter kombiniert werden konnen.
Ein Filter ist ein sequentieller Datenstrom, der auf einem anderen
sequentiellen Datenstrom aufbaut.
Filter stellt immer einen Konstruktor zur Verfu gung, der den
darunterliegenden Datenstrom als Parameter bekommt.
Klasse File
Klasse File reprasentiert einen Directory-Eintrag, der entweder
ein einzelnes File oder ein Directory darstellt.
Unterscheidung inkl. Existenztest mit Methoden
boolean isFile();
boolean isDirectory();
Nur Directory-Information kann u ber File-Instanzen abgefragt
werden. File erlaubt nicht das Lesen oder Schreiben des Inhalts.
O ffnen von Files (Zugriff auf Inhalt) durch Konstruktoren fu r
Datenstrome. Diese sind u berladen (File-Parameter, Pfadnamen,
etc.).
Bei Pfadnamen kann (unter Windows und Unix) '/' als DirectorySeparator verwendet werden (allgemein: File.separator).
Klasse RandomAccessFile wird verwendet, wenn direkter Zugriff
zu Dateiinhalt an einer bestimmten Position erforderlich ist.
Bytestrome
Abstrakte Klasse InputStream definiert Operationen zum
sequentiellen Lesen von einzelnen Bytes und von Byte-Arrays.
Konkrete Klasse FileInputStream liest Bytes von einem File.
Konkrete Filterklasse BufferedInputStream erlaubt gepuffertes
Lesen der Bytes => wesentlich schneller!
InputStream in = new BufferedInputStream(
new FileInputStream("inputFile"));
int b = in.read();
while (b >= 0) { ... }
in.close();
read() liefert unsigned Bytes (0..255) oder ß 1 zur Kennzeichnung
von end-of-file. Daher int als Ergebnistyp verwendet.
Abstrakte Klasse OutputStream definiert Methoden zum
sequentiellen Schreiben von einzelnen Bytes und von Byte-Arrays.
Konkrete Klasse FileOutputStream schreibt Bytes auf ein File.
Konkrete Filterklasse BufferedOutputStream erlaubt
gepuffertes Schreiben der Bytes => wesentlich schneller!
OutputStream out = new BufferedOutputStream(
new FileOutputStream("outputFile"));
out.write((byte)42); ...
out.flush();
out.write((byte)77); ...
out.close();
Die flush()-Operation schreibt allfallige gepufferte Bytes auf das
Ausgabemedium.
Zeichenstro me
Analog zu Bytestromen aber unter Verwendung der Namen
Reader und Writer statt InputStream und OutputStream.
Zum Beispiel schreibt ein FileWriter einen Zeichenstrom in eine
Datei.
Problem: Files sind byte-orientiert. Daher Abbildung von Zeichen
auf Bytes erforderlich. FileReader/-Writer verwendet DefaultEncoding der Plattform.
Zur expliziten Kontrolle des Encodings verwendet man
InputStreamReader bzw. OutputStreamWriter.
Beispiel:
Writer out = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("name"),
"UTF8" //encoding parameter
));
Serialisierung von Daten
Programme arbeiten selten direkt auf Byte-Ebene sondern
meistens mit den primitiven Java-Datentypen und/oder Klassen.
Die Abbildung von Daten in Bytestrome heisst Serialisierung. Die
Umkehrung hei t Deserialisierung.
Datenstro me
Zur Serialisierung primitiver Java-Datentypen (int, boolean, char,
etc.), wird ein Datenstrom verwendet, das ist ein Strom, der die
Schnittstelle DataInput bzw. DataOutput implementiert.
Zur Implementierung von Datenstromen basierend auf Bytestromen
existieren die konkreten Filter-Klassen DataOutputStream bzw.
DataInputStream mit Lese-Schreiboperation fu r alle primitiven
Java Datentypen (z.B. writeBoolean, writeDouble,
writeUTF).
Die Abbildung der Datentypen ist plattformunabhangig. Auf diese
Weise geschriebene Files sind also portabel.
Objektstro me
Zur Serialisierung von Objekten wird ein Objektstrom verwendet.
das ist ein Datenstrom, der zusatzlich die Schnittstelle
ObjectInput bzw. ObjectOutput mit Methoden readObject
bzw. writeObject implementiert.
Zur Implementierung von Objektstromen basierend auf
Bytestromen existieren die konkreten Filter-Klassen
ObjectInputStream und ObjectOutputStream.
Das Serialisieren von Objekten besteht aus dem Serialisieren der
Typinformation (Klasse) plus (im Normalfall) dem Serialisieren aller
Instanzvariablen, die nicht als transient markiert sind.
Voraussetzung: Klasse muss Schnittstelle Serializable
implementieren, sonst Exception.
Referenzen auf andere Objekte (die Serializable sind) werden
ebenfalls serialisiert, so dass ein ganzer Graph von Objekten
(transitive Hu lle) geschrieben wird.
Die Identitat von Objekten, die mehrfach referenziert werden, bleibt
erhalten. Beim Deserialisieren bekommt man eine exakte Kopie der
transitiven Hu lle eines serialisierten Objekts.
Beieinflussung der Serialisierung von Objekten
Durch Implementieren von optionalen Methoden.
Details siehe javadoc von Serializable.
1. writeObject und/oder readObject
Damit kann eine Klasse selbst das Serialisieren/Deserialisieren
ihrer eigenen Instanzvariablen ausprogrammieren.
Die Instanzvariablen der Basisklasse(n) sind davon nicht betroffen.
Die Methoden mu ssen exakt diese Signatur aufweisen:
private void writeObject(ObjectOutputStream out)
throws IOException
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException;
2. writeReplace und/oder readResolve
Damit kann ein Objekt beim Serialisieren/Deserialisieren durch ein
anderes Objekt ersetzt werden.
Anwendungsbeispiel: ein 'Remote'-Objekt konnte beim Schreiben
durch eine Objekt-Referenz ersetzt werden. Beim Lesen konnte die
Objekt-Referenz client-seitig durch ein Stub-Objekt ersetzt werden
und server-seitig durch das Server-Objekt.
Die Methoden konnen beliebige Sichtbarkeit aufweisen.
ANY-ACCESS-MODIFIER Object writeReplace()
throws ObjectStreamException;
ANY-ACCESS-MODIFIER Object readResolve()
throws ObjectStreamException;
Klassendiagramm Streams
Object
File
FileDescriptor
StreamTokenizer
OutputStream
DataOutput
ObjectOutput
InputStream
RandomAccessFile
DataInput
ObjectOutputStream
ObjectInputStream
FilterOutputStream
FilterInputStream
PrintStream
LineNumberInputStream
BufferedOutputStream
DataInputStream
DataOutputStream
BufferedInputStream
ByteArrayOutputStream
PushbackInputStream
PipedOutputStream
ByteArrayInputStream
FileOutputStream
PipedInputStream
FileInputStream
SequenceInputStream
StringBufferInputStream
ObjectInput
Klassendiagramm Readers/Writers
Herunterladen