Ein- und Ausgabeströme in Java 1.4 Denis Stein 19. Mai 2004 Denis Stein Ein- und Ausgabeströme in Java 1.4 Inhalte dieses Vortrages • Datenströme und Dateien • InputStream und OutputStream • Reader und Writer • Arbeit mit Textdateien und Datendateien • Objektserialisierung • weitere Möglichkeiten 1 Denis Stein Ein- und Ausgabeströme in Java 1.4 Datenströme (engl. Streams) und Dateien • Datenströme: Schnittstelle von Java-Anwendungen zur Außenwelt, d.h. Kommunikation u.a. mit Nutzer (Ausnahme: GUI) • Eingabeströme: z.B. Daten von Tastatur, aus Dateien oder Netzwerk • Ausgabeströme: z.B. Daten in Dateien oder für Drucker • Datei: Menge logisch zusammenhängender Daten • enge Verknüpfung zwischen Datenströmen und Dateien 2 Denis Stein Ein- und Ausgabeströme in Java 1.4 Datenströme • FIFO-Prinzip, unidirektional à sequentieller Zugriff (wahlfreier Zugriff auf Dateien durch java.io.RandomAccessFile) • Prinzip: Stream schreiben−→ puffern −→lesen • sind Objekte (insbesondere im Package java.io) • Ein- und Auslesen meist innerhalb von try/catch-Blöcken (wegen Exception) • Schachtelung möglich (Verbinden mehrerer Streams, im Konstruktor) 3 Denis Stein Ein- und Ausgabeströme in Java 1.4 • 3 (UNIX)-Standardstreams in, out, err sind Konstanten in Klasse System à ohne Instanziierung verwendbar out in −→ Tastatur −→ Computer err Monitor −→ • Einteilung: Streams byteorientiert InputStream OutputStream unicodeorientiert Reader Writer 4 Denis Stein Ein- und Ausgabeströme in Java 1.4 InputStream und OutputStream • beides abstrakte byteorientierte Ströme • jeweils nur 1 Methode nicht implementiert • InputStream – Lesen eines oder mehrerer Bytes mit read() – close() zum Schließen – einige Unterklassen: FileInputStream, FilterInputStream, ObjectInputStream – System.in Instanz von BufferedInputStream 5 Denis Stein Ein- und Ausgabeströme in Java 1.4 • OutputStream – – – – Schreiben eines einzelnen Bytes mit write() flush() um Pufferinhalt auszuschreiben auch hier close() zum Schließen einige Unterklassen: FileOutputStream, FilterOutputStream, ObjectOutputStream – System.out, err Instanzen von PrintStream (Unterklasse von FilterOutputStream) à Beispiel InAndOutput.java 6 Denis Stein Ein- und Ausgabeströme in Java 1.4 Reader und Writer • abstrakte Klassen für zeichenorientierte Ströme • seit JDK 1.1 • Aufbau ähnlich der Byteströme • Reader – read() liest einzelnes Zeichen oder mehrere in Characterarray – close() zum Schließen – einige Unterklassen: BufferedReader, FilterReader, InputStreamReader 7 Denis Stein Ein- und Ausgabeströme in Java 1.4 • Writer – – – – write()-Methoden schreiben jeweils ein oder mehrere Zeichen oder String s flush() zum Leeren des Puffers close() zum Schließen einige Unterklassen: BufferedWriter, FilterWriter, OutputStreamWriter 8 Denis Stein Ein- und Ausgabeströme in Java 1.4 InputStreamReader und OutputStreamWriter, BufferedReader und BufferedWriter • InputStreamReader liest Bytes und wandelt diese in Characterstrom um (hier noch Array nötig) • OutputStreamWriter schreibt Zeichen und wandelt diese in Bytestrom um • BufferedReader – puffert Eingabe à Performancegewinn, da größere Leseoperationen möglich – bietet Möglichkeit gesamte Zeile als String auszulesen (readLine()) 9 Denis Stein Ein- und Ausgabeströme in Java 1.4 • BufferedWriter – puffert Ausgabe und führt mehrere Schreiboperationen als Ganzes aus – newLine() um Zeilentrennzeichen zu schreiben • Verbesserung des Beispiels: Schachtelung von 3 Streamobjekten System.in input inReader bufferIn (InputStream) → (InputStreamReader ) → (BufferedReader ) → (String ) • Vorteile: – kein Array (unbekannter) Größe – keine explizite Stringerzeugung à Beispiel InAndOutput2.java 10 Denis Stein Ein- und Ausgabeströme in Java 1.4 Arbeiten mit Textdateien • Klassen FileReader und FileWriter bieten keine neuen Methoden (Unterklassen von InputStreamReader bzw. OutputStreamWriter ) • Probleme beim Lesen aus Textdatei – auch hier Array nötig – nur zeichenweise à hohe Belastung des Datenträgers • Lösung: Schachtelung mit BufferedReader à Beispiel TextFile.java 11 Denis Stein Ein- und Ausgabeströme in Java 1.4 • Schreiben in Textdatei verläuft ähnlich • Beachte: Daten erst nach close() auf Festplatte geschrieben • Einlesen von Tastatur (readLine()) System.in input inReader bufferIn (InputStream) → (InputStreamReader ) → (BufferedReader ) → (String ) • Schreiben in Textdatei (write()) input topics bufferOut fWriter (String ) → (BufferedWriter ) → (FileWriter ) → (Datei) à Beispiel TextFile2.java 12 Denis Stein Ein- und Ausgabeströme in Java 1.4 Arbeiten mit Datendateien • Unterschied zu Textdateien – nicht vom Menschen lesbar“ ” – kein Zeilenendezeichen à kein zeilenweises Lesen • speichern Java-Datentypen (int, float,. . . ) in Maschinendarstellung à keine Konvertierung nötig • Klassen FileInputStream und FileOutputStream zum Lesen und Schreiben von Byteströmen aus bzw. in Dateien • Größe von ausgewählten Javadatentypen: boolean 1 Byte, char 2 Byte, int 4 Byte, double 8 Byte 13 Denis Stein Ein- und Ausgabeströme in Java 1.4 • Problem: wie kommen diese unterschiedlichen Datentypen in Bytestrom? • Lösung: Verknüpfung mit DataInputStream bzw. DataOutputStream – Unterklassen von FilterInputStream bzw. FilterOutputStream, welche ggf. Daten transformieren – können jeden primitiven Datentyp mittels readType() lesen bzw. writeType() schreiben – DataOutputStream auf jedem Javasystem wieder einlesbar, da genaue Festlegung der Kodierung à Beispiel DataFile.java 14 Denis Stein Ein- und Ausgabeströme in Java 1.4 Objektserialisierung • Serialisierung: Objekte durch Streams in Bytes zerlegen • Deserialisierung: Objekte aus byteorientiertem Strom wieder zusammensetzen • Klassen: ObjectInputStream und ObjectOutputStream (seit JDK 1.1) – Lesen bzw. Schreiben von Objekten mittels readObject() bzw. writeObject() – auch jeder primitive Datentyp kann mittels readType() und writeType() behandelt werden • Klassen standardmäßig nicht serialisierbar, sondern erst wenn sie Interface java.io.Serializable implementieren 15 Denis Stein Ein- und Ausgabeströme in Java 1.4 • Variablenwerte mit Schlüsselwort transient werden nicht gespeichert • Ablauf der Objektserialisierung – Objekttyp – nichtstatische und nichttransiente Attribute und deren Werte gespeichert (auch von Oberklassen) – jeweils rekursiv (Attribute können auch Objekte sein) – alles genau 1 Mal gespeichert – keine unendliche Rekursion • Ablauf der Deserialisierung – Objekt der Klasse angelegt – gespeicherte Daten eingelesen und diesem Objekt zugewiesen“ ” 16 Denis Stein Ein- und Ausgabeströme in Java 1.4 • bei Deserialisierung explizite Typumwandlung erforderlich (da Rückgabewert Object) • außerdem muss bei Objekten Bytecode der zu deserialisierenden Klasse vorhanden sein • auch Serialisierung von Objekten in XML möglich (java.beans.XMLEncoder bzw. java.beans.XMLDecoder, seit Version 1.4) à Beispiel XML.java 17 Denis Stein Ein- und Ausgabeströme in Java 1.4 weitere Möglichkeiten • Klasse java.io.File zur plattformunabhängigen Beschreibung von Dateien und Verzeichnissen – Informationen wie Pfad, Rechte, Änderungsdatum – Erstellen, Löschen und Umbenennen von Dateien und Verzeichnissen – Anzeigen von Verzeichnisinhalten • filternde Zeichenströme mittels abstrakter Klassen FilterReader und FilterWriter • lexikalische Analyse mit Hilfe von PushbackReader (filternder Charaktereingabestrom, der Zeichen wieder in Strom zurücklegen kann) 18 Denis Stein Ein- und Ausgabeströme in Java 1.4 • (De-)Komprimieren von Dateien mit Hilfe von byteorientierten Streamklassen GZIPInputStream und GZIPOutputStream aus Package java.util.zip • Verschlüsselung von Datenströmen mit javax.crypto.CipherInputStream und javax.crypto.CipherOutputStream • uni- sowie bidirektionale Kommunikation zwischen Threads möglich (PipedInputStream und PipedOutputStream bzw. PipedReader und PipedWriter ) 19 Denis Stein Ein- und Ausgabeströme in Java 1.4 verwendete Literatur • JavaTM 2 Platform, Standard Edition, v 1.4.2 API Specification • Krüger - Go To Java 2 (2. Auflage) • Niemann - Objektorientierte Programmierung in Java (3. überarbeitete Auflage) • Ullenboom - Java ist auch eine Insel (3. Auflage) 20 Denis Stein Ein- und Ausgabeströme in Java 1.4 Und zum Schluss. . . Die Folien sowie Beispieldateien gibt es unter: http://www.inf.tu-dresden.de/~s3409194/proseminar 21