Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Telecooperation/RBG Technische Universität Darmstadt Copyrighted material; for TUD student use only Grundlagen der Informatik 1 Thema 20: Ströme und Ein-/Ausgabe.

Ähnliche Präsentationen


Präsentation zum Thema: "Telecooperation/RBG Technische Universität Darmstadt Copyrighted material; for TUD student use only Grundlagen der Informatik 1 Thema 20: Ströme und Ein-/Ausgabe."—  Präsentation transkript:

1 Telecooperation/RBG Technische Universität Darmstadt Copyrighted material; for TUD student use only Grundlagen der Informatik 1 Thema 20: Ströme und Ein-/Ausgabe in Java Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

2 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Inhaltsverzeichnis Einführung in Eingabe-/Ausgabe-Ströme und Java Ein-/Ausgabe (Input/Output, I/O) Einblick in Prozessströme Schachtelung von Stromobjekten und das Decorator-Muster Selbstdefinierte Ströme, StreamTokenizer und wahlfreier Zugriff 2

3 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Eingabe /Ausgabe (Input / Output, I/O) Bislang: –Eingabedaten sind entweder fest im Quelltext codiert oder werden als Parameter beim Programmstart von der Konsole übergeben define in Scheme Variablendeklaration und Initialisierung in Java Tatsächliche Parameterwerte in Funktionsaufrufen von Scheme args Parameter in main –Ausgaben des Programms wurden auf dem Bildschirm ausgegeben Probleme: –Closed World keine Interaktion mit der Außenwelt Keine Einflussnahme auf den Programmablauf nach dem Start –Ergebnisse können nicht dauerhaft gespeichert werden Diese Vorlesung widmet sich anderer Möglichkeiten der Ein- /Ausgabe in Java 3

4 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 I/O-Ströme Verschiedene Quellen/Senken für die Daten –Tastatureingabe (Standard I/O) –Datei(en) auf dem lokalen Rechner (File I/O) –Datei(en)/Prozess(e) im Netzwerk (Network I/O) –Hauptspeicher (Memory I/O) Um einheitlich Daten auf unterschiedliche Datenbehälter ein-/auszugeben, verwendet Java das Konzept der Streams (Ströme) –Eingabe- und Ausgabeströme (E/A, engl. I/O) Datenströme als eine Abstraktion von I/O Geräten –Verstecken Details über die Implementierung / Funktionsweise der einzelnen I/O-Geräte vor dem Java Programmierer Tastatur, Datei, anderes Programm, Netz, Hauptspeicher, … –Stellen Java-Programmen einheitliche Schnittstellen zum Lesen bzw. Schreiben von Daten zur Verfügung –Das Java Programm spricht mit Java I/O Objekten 4

5 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 I/O-Ströme Um Daten von einer externen Datenquelle zu lesen, öffnet ein Java-Programm einen Eingabestrom und liest die Daten seriell (nacheinander) ein: 5 Um Daten in eine externe Senke zu schreiben, öffnet ein Java-Programm einen Ausgabestrom und schreibt die Daten seriell

6 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Ströme und verzögerte Listen Das Konzept der Ströme ist allgemeiner und nicht nur für I/O geeignet Die Idee haben wir bereits in Scheme kennen gelernt –Verzögerte Listen –Möglichkeit, virtuelle Listen zu erzeugen –Wir konnten transparent Daten mit first und rest verknüpfen Diese Idee passt sehr gut zu I/O –Input: Lese den Eingabewert beim Zugriff auf das nächste Listenelement –Output: Beim Erweitern der Liste Ausgabewert schreiben –Eingabestream verzögerte Liste ohne cons –Ausgabestream verzögerte Liste ohne first/rest 6

7 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Vordefinierte Ströme in java.io 7 Zwei Klassifizierungen von Datenströmen: –Nach dem Datentyp –Nach der Struktur der Ströme

8 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Klassifizierung der Ströme Nach dem Datentyp –Zeichenströme lesen / schreiben char (16-bit Unicode Zeichensatz) –Byteströme lesen / schreiben byte (8-bit) Werden zum Lesen bzw. Schreiben von Binärdaten, z.B. Bildern, benutzt Nach der Struktur der Ströme: –Datensenkeströme: Daten werden direkt von physikalischer Datenquelle gelesen bzw. auf physikalische Datensenke geschrieben –Prozessströme: Daten werden von anderen Strömen gelesen bzw. auf andere Ströme geschrieben Daten werden nach dem Lesen bzw. vor dem Schreiben gefiltert, gepuffert, bearbeitet, usw. 8

9 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Hierarchie der Datenströme in Java Zeichenströme –java.io.Reader/java.io.Writer stellen die Schnittstelle und eine partielle Implementierung von Zeichenströmen zur Verfügung –Subklassen von Reader/Writer fügen neues Verhalten hinzu bzw. ändern dieses. Byteströme –java.io.InputStream/java.io.OutputStream: gemeinsame Schnittstelle und partielle Implementierung für alle Ströme zum Lesen bzw. Schreiben von Bytes Alle anderen Byteströme sind Unterklassen davon 9

10 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Hierarchie der Zeichenströme (Auszug) 10 Reader StringReader InputStreamReader FilterReader FileReader PushbackReader LineNumberReader BufferedReader PrintWriter StringWriter FilterWriter BufferedWriter Writer OutputStreamWriter FileWriter Die Klassen in schattierten Kästchen sind Prozessströme

11 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Hierarchie der Byteströme (Auszug) 11 InputStream OutputStream FileInputStream PipedInputStream FilterInputStream ByteArrayInputStream ObjectInputStream SequenceInputStream StringBufferInputStream LineNumberInputStream BufferedInputStream PushbackInputStream DataInputStream FileOutputStream PipedOutputStream ByteArrayOutputStream FilterOutputStream ObjectOutputStream PrintStream DataOutputStream BufferedOutputStream Die Klassen in schattierten Kästchen sind Prozessströme

12 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Datensenke-Ströme: Überblick 12 Senke TypZeichenströmeByteströme Hauptspeicher Pipe Datei CharArrayReader, CharArrayWriter StringReader, StringWriter PipedReader, PipedWriter FileReader, FileWriter ByteArrayInputStream, ByteArrayOutputStream StringBufferInputStream PipedInputStream, PipedOutputStream FileInputStream, FileOutputStream CharArrayReader/CharArrayWriter ByteArrayInputStream/ByteArrayOutputStream Lesen / Schreiben von / auf Arrays StringReader/StringWriter, StringBufferInputStream – Lesen / Schreiben von / auf Strings im Hauptspeicher FileReader/FileWriter, FileInputStream/FileOutputStream – Lesen / Schreiben von / auf Dateien

13 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Gemeinsame Muster der I/O-Ströme Lesen/Schreiben von/auf Strömen haben unabhängig von Datentyp und Quelle bzw. Senke die gleiche Form Lesen Öffne einen Strom Ströme werden beim Erzeugen automatisch geöffnet Lese Daten, solange nötig und es noch Daten gibt Schließe den Strom Bei Beenden des Lesens bzw. Schreibens sollte der Strom durch close() geschlossen werden! Schreiben Öffne einen Strom Solange es noch Daten gibt, schreibe Daten Schließe den Strom 13

14 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 I/O-Oberklassen 14 InputStream public int read() public int read(byte[] bbuf) public int read(byte[] bbuf, int offset, int len) Reader public int read() public int read(char[] cbuf) public int read(char[] cbuf, int offset, int len) OutputStream public int write(int b) public int write(byte[] bbuf) public int write(byte[] bbuf, int offset, int len) Writer public int write(int c) public int write(char[] cbuf) public int write(char[] cbuf, int offset, int len) Nutze I/O Ströme nur über allgemeines Interface Information Hiding durch Subtyppolymorphie

15 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Die Klasse java.io.Reader 15 Für weitere Details siehe API Spezifikation public int read(char[] c) throws IOException public long skip(long n) throws IOException public void reset() throws IOException public int close() throws IOException... public abstract int read(char[] c) throws IOException –Liest die nächsten Unicode-Zeichen im Strom in ein Array –Gibt die Anzahl der gelesenen Zeichen zurück oder -1, falls das Ende der Datei erreicht wurde (EOF) –IOException bei allen anderen Problemen Z.B. Strom bereits geschlossen, Netzwerkverbindung verloren

16 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Java Dokumentation 16

17 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Java Dokumentation 17

18 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Dateiströme Dateiströme sind Ein-/Ausgabe-Ströme, deren Quellen/Senken Dateien im Dateisystem sind –FileReader / FileWriter für Lesen / Schreiben von Zeichen aus/in Dateien – Analog dazu: FileInputStream, FileOutputStream für Lesen / Schreiben von Bytes von/in Dateien Ein Dateistrom kann erzeugt werden, indem man die Quelle- bzw. Senke-Datei durch eines der folgenden Objekte als Parameter des Strom-Konstruktors übergibt – Dateiname ( String ) – Datei-Objekt ( java.io.File ) – Dateibeschreibung ( java.io.FileDescriptor ) 18

19 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Die Klasse java.io.FileReader 19 Beispiel: Ausgeben eines Dateiinhalts auf den Bildschirm (Ausgabe erfolgt als Integer-Werte!) und Zeichen von 'a' bis 'z' in eine Datei schreiben import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class ReadWriteFile { // Konstruktor etc. public void readFrom(String fileName) throws IOException { FileReader in = new FileReader(fileName); int b; while ((b = in.read()) != -1) System.out.print(b); in.close(); } public void writeAToZ(String filename) throws IOException { FileWriter out = new FileWriter(filename); for (char c = 'a'; c <= 'z'; c++) out.write(c); out.close(); } // main etc. }

20 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Inhaltsverzeichnis Einführung in Ein-/Ausgabe-Ströme und Java Ein- /Ausgabe (Input/Output, I/O) Einblick in Prozessströme Schachtelung von Stromobjekten und das Decorator-Muster Selbstdefinierte Ströme, StreamTokenizer und wahlfreier Zugriff 20

21 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Prozess-Ströme Ein Prozess-Strom enthält einen anderen (Daten- oder Prozess-)Strom –Dieser dient als Quelle bzw. Senke Prozess-Ströme ändern Daten oder bieten Funktionalität –Zwischenspeichern (Puffern) von Daten –Zählen der gelesenen/geschriebenen Zeilen –Konvertierung zwischen Byte und Zeichen –Kompression, … 21 Datensenke Prozess-Datenstrom Datenquelle Originaler Datenstrom

22 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Prozess-Ströme 22 AufgabeZeichenströmeByteströme Filtern Puffern Byte / Zeichen Konvertierung Zählen Unterstützung für Datentypen Rückgängig machen Ausgeben FilterReader, FilterWriter FilterInputStream, FilterOutputStream BufferedReader, BufferedWriter BufferedInputStream, BufferedInputStream InputStreamReader, OutputStreamWriter LineNumberReader LineNumberInputStream DataInputStream, DataOutputStream PushbackReader PushbackInputStream PrintWriter PrintStream byte char char byte

23 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Die Wurzel der Prozess-Ströme FilterReader/FilterWriter bzw. FilterInputStream/FilterOutputStream sind Superklassen für alle Prozessströme Kapseln einen internen Strom in Defaultimplementierung einer Operation op : delegiere op weiter an in (in.op()) Konkrete Unterklassen redefinieren diese Funktionalität 23

24 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Java Dokumentation 24

25 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Pufferströme Ein Pufferstrom kapselt einen anderen Datenstrom und einen internen Puffer Beim ersten Lesen wird der Puffer vollständig gefüllt –Weitere Lese-Operationen liefern Bytes vom Puffer zurück, ohne vom unterliegenden Strom tatsächlich zu lesen –Bei leerem Puffer wird erneut vom unterliegenden Strom gelesen Beim Schreiben werden die Daten zuerst in dem internen Puffer gespeichert, bevor sie in den unterliegenden Strom geschrieben werden –Nur wenn der Puffer voll ist, wird auf den unterliegenden Strom geschrieben –Sowie bei explizitem Aufruf der Methode flush() oder close() 25

26 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Pufferströme BufferedReader und BufferedWriter bieten die Standard- Schnittstelle und Implementierung für Zeichenströme mit Pufferung an –Unterklassen von Reader bzw. Writer BufferedInputStream und BufferedOutputStream bieten die Standard-Schnittstelle und Implementierung für Byteströme mit Pufferung an –Unterklassen von FilterInputStream bzw. FilterOutputStream 26

27 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Pufferströme 27 Datensenke Programm BufferedWriter b write bbuf write bbuf write bbuf flush

28 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Pufferströme: Performanz 28 Lesen einer 2.5 MB-Datei (x: Puffergröße, y: Zeit [ms] PuffergrößeTime[ms]

29 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 DataInputStream / DataOutputStream 29 Diese Ströme ermöglichen das Lesen/Schreiben von primitiven Java Datentypen in einem maschinenunabhängigen Format. Ein DataOutputStream wird verwendet, um Daten zu schreiben, die später von einem DataInputStream gelesen werden sollen. FilterInputStream DataInputStream readBoolean(): boolean readByte(): byte readShort() : short readChar() : char readInt() : int readFloat() : float FilterOutputStream DataOutputStream writeBoolean(boolean) : void writeByte(byte) : void writeShort(short) : void writeChar(char) : void writeInt(int) : void writeFloat(float) : void > DataInput > DataOutput

30 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Datenströme: Beispiel 30 import java.io.FileOutputStream; import java.io.DataOutputStream; import java.io.IOException; public class DataStreamExample { String fileName = "hello.txt";// ein Dateiname // ein paar Methoden public void writeData() throws IOException { FileOutputStream fos = new FileOutputStream(filename); DataOutputStream out = new DataOutputStream(fos); out.writeInt(9); out.writeDouble(Math.PI); out.writeBoolean(true); out.close(); } // weitere Methoden public void readData() throws IOException { FileInputStream fis = new FileInputStream(fileName); DataInputStream in = new DataInputStream(fis); int i = in.readInt(); double d = in.readDouble(); boolean b = in.readBoolean(); in.close(); System.out.println("Gelesen: "+ i + ", " + d + ", und " + b+ "."); } }

31 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Standard-I/O Im Paket java.lang gibt es die Klasse System mit den folgenden Klassenvariablen: System.in Standardeingabe (Tastatur) System.out Standardausgabe (Bildschirm) System.err Fehlermeldungen (Bildschirm) System.in ist ein Objekt vom Typ InputStream –Stellt read() zum byte-weisen Lesen von Bytes von der Tastatur zur Verfügung System.out, System.err sind vom Typ PrintStream –Bieten print() und println() zur Datenausgabe an 31

32 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 PrintStream 32 FilterOutputStream PrintStream print(boolean) : void print(double) : void print(char) : void print(double) : void print(float) : void... println(Object): void println(String): void... Ermöglicht das einfache Schreiben von diversen Datentypen in einer üblichen Repräsentation Wirft niemals eine IOException –Auftretende Exceptions setzen ein internes Flag, das durch die checkError Methode getestet werden kann Alle Zeichen, die mit einem PrintStream geschrieben werden, werden mit dem Standardzeichensatz der Plattform konvertiert –PrintWriter sollte in Situationen eingesetzt werden, in denen Zeichen (anstelle von Bytes) geschrieben werden

33 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Inhaltsverzeichnis Einführung in Ein-/Ausgabe-Ströme und Java Ein- /Ausgabe (Input/Output, I/O) Einblick in Prozessströme Schachtelung von Stromobjekten und das Decorator-Muster Selbstdefinierte Ströme, StreamTokenizer und wahlfreier Zugriff 33

34 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Verschachtelung der Ströme 34 Ströme können ineinander verschachtelt werden Abstraktionsebenen, bei denen unterliegende primitive Ströme von umschließenden (höheren, komfortableren) Strömen benutzt werden (Prozessströme) Datensenke, z.B. Datei FileOutputStream BufferedOutputStream ZipOutputStream // erzeugt gepufferten, komprimierenden Dateiausgabestrom OutputStream out = new FileOutputStream(filename); out = new BufferedOutputStream(out); out = new ZipOutputStream(out); // … mehr Eigenschaften koennen dynamisch hinzugefuegt werden // Die Stromeigenschaften sind unsichtbar fuer Klienten

35 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Architektur von Java Streams Die Technik, mit der erreicht wird, dass Ströme beliebig zur Laufzeit kombiniert werden können, ist nicht nur im Kontext von Strömen von Interesse. –Generelle Technik, um Objekte dynamisch mit Features zu erweiterten In der Softwaretechnik werden solche Techniken in der Form so genannter Entwurfsmuster (design patterns) dokumentiert. –Wieder verwendbare, dokumentierte Designideen –Mehr in der Hauptstudiumsvorlesung SE Design Die oben genannte Technik bei Streams ist als Decorator Pattern bekannt. 35

36 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Inhaltsverzeichnis Einführung in Ein-/Ausgabe-Ströme und Java Ein- /Ausgabe (Input/Output, I/O) Einblick in Prozessströme Schachtelung von Stromobjekten und das Decorator-Muster Selbstdefinierte Ströme, StreamTokenizer und wahlfreier Zugriff 36

37 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Selbstdefinierte Prozessströme Oft möchten Programmierer eigene Ströme definieren, die Daten filtern und/oder verarbeiten, die von einem anderen Strom gelesen/geschrieben werden Eigene Filterung oder Verarbeitung kann implementiert werden, indem man von FilterReader/FilterInputStream bzw. FilterWriter/FilterOutputStream erbt Es folgt ein Beispiel eines selbstdefinierten Filterstroms auf Datenströmen, der alle Zeilen im unterliegenden Strom herausfiltert, die einen bestimmten Substring enthalten – Unix "grep" Befehl 37

38 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Selbstdefinierte Prozessströme 38 import java.io.BufferedReader; import java.io.FilterReader; import java.io.IOException; class GrepReader extends FilterReader { String substring; BufferedReader in; GrepReader(BufferedReader reader, String pattern) { super(reader); in = reader; substring = pattern; } // return the next line containing the search pattern String readLine() throws IOException { String line; while (((line = in.readLine()) != null) && (line.indexOf(substring) == -1)) ; return line; } }

39 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 import java.io.*; public class Grep { public static void main(String[] args) { if ((args.length == 0) || (args.length > 2)) { System.out.println("Usage: java Grep [ ]"); System.exit(0); } try { Reader d; if (args.length == 2) d = new FileReader(args[1]); else d = new InputStreamReader(System.in); GrepReader g = new GrepReader(new BufferedReader(d), args[0]); String line; while ((line = g.readLine()) != null) System.out.println(line); g.close(); } catch (IOException e) { System.err.println(e); } } } Selbstdefinierte Prozessströme 39 Durchsuchter Datenstrom Zu findendes Muster

40 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Wahlfreier Zugriff Bisher: Ströme, deren Inhalt nur in einer sequentiellen Weise gelesen bzw. geschrieben werden kann Sequentielle Dateien passen gut zu sequentiellen Speichermedien, z.B. Magnetbänder Random Access Files erlauben nicht-sequentielle (wahlfreie) Zugriffe auf den Inhalt einer Datei 40

41 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Warum wahlfreier Zugriff? Gegeben ein Dateiarchiv in.zip Format: –Zip-Archive bestehen aus Dateien und sind meist komprimiert, um Speicher zu sparen –Außer Dateien haben Zip-Archive ganz zum Schluss zusätzlich einen so genannten Dir-Eintrag (von Directory, engl. Verzeichnis) –Hier wird gespeichert, welche Dateien enthalten sind und wo die einzelnen Dateien innerhalb des Archivs anfangen Aufgabe: eine bestimmte Datei aus dem Archiv extrahieren 41

42 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Darum wahlfreier Zugriff! Verfahren für einen sequentiellen Strom: –Suche durch das ganze Archiv, bis die gewünschte Datei lokalisiert ist –Extrahiere die Datei Im Durchschnitt wird die Hälfte der Einträge im Archiv gelesen, bevor die gewünschte Datei gefunden ist Strom mit wahlfreiem Zugriff: –Springe zum Dir-Eintrag und lese den Eintrag der gesuchten Datei –Springe rückwärts zu der Position der Datei –Extrahiere die Datei Man muss genau zwei Einträge lesen: dir-entry and file Das Verfahren ist also wesentlich effizienter! 42

43 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Wahlfreier Zugriff in Java 43 Realisiert durch die Klasse RandomAccessFile Kann für Lesen und Schreiben benutzt werden - implementiert Schnittstellen DataInput und DataOutput Ähnelt FileInputStream und FileOutputStream, indem man ein RandomAccessFile auf eine Datei öffnet und beim Erzeugen den Dateinamen oder ein File- Objekt als Parameter übergibt: Außerdem muss beim Erzeugen spezifiziert werden, ob die Datei nur zum Lesen oder auch zum Schreiben geöffnet wird –Man muss eine Datei lesen können, um auf sie schreiben zu können

44 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Wahlfreier Zugriff in Java Erzeugen eines RandomAccessFile, um die Datei random.txt zu lesen: –new RandomAccessFile("random.txt", "r"); Erzeugen eines RandomAccessFile, um die Datei random.txt zu lesen und zu schreiben: –new RandomAccessFile("random.txt", "rw"); Nachdem die Datei geöffnet ist, kann mit den read und write-Operationen gelesen bzw. geschrieben werden 44

45 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Wahlfreier Zugriff in Java RandomAccessFile unterstützt einen Datei-Zeiger –indiziert die aktuelle Dateiposition Beim Erzeugen ist der Datei-Zeiger 0 - der Anfang der Datei Aufrufe von read / write- Operationen verschieben den Datei-Zeiger automatisch um die Anzahl der gelesenen bzw. geschriebenen Bytes 45 RandomAccessFile unterstützt zusätzlich Operationen zum Manipulieren des Zeigers: –public int skipBytes(int n) throws IOException Verschiebt den Zeiger vorwärts um n Bytes –public native void seek(long pos) throws IOException Positioniert den Zeiger genau vor das Byte an der Stelle pos –public native long getFilePointer() throws IOException Gibt die aktuelle Position in der Datei zurück

46 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Stromverarbeitung mit StreamTokenizer java.io.StreamTokenizer unterstützt die Zerlegung von Zeichenströmen in Symbole (Tokens) Lesen des nächsten Tokens durch nextToken() –Überspringt Whitespace (leere Zeichen) Was als Whitespace angesehen wird, ist konfigurierbar –Der Typ des gelesenen Tokens wird über das Attribut ttype abgefragt Die Tokenarten werden auf der folgenden Folie vorgestellt 46

47 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 StreamTokenizer: Tokenarten StreamTokenizer.TT_NUMBER: Zahl erkannt, nval enthält die Zahl StreamTokenizer.TT_WORD: Wort erkannt, sval enthält das Wort StreamTokenizer.TT_EOL: Zeilenende ist erkannt –Wird nur dann als Token erkannt, wenn der Tokenizer entsprechend konfiguriert wurde ( eolIsSignificant(true) ) StreamTokenizer.TT_EOF – Dateiende wurde erreicht Sonstiges – ttype codiert ein Zeichen, etwa '$', ';' 47

48 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Anpassung von StreamTokenizer public void wordChars(int low, int hi) –Definieren, was als Wortbestandteil gelten soll –Alle Zeichen im Intervall [low, hi] zählen als Wortbestandteile public void whitespaceChars(int low, int hi) –Definieren von Leerzeichen –Alle Zeichen im Intervall [low, hi] zählen als Leerzeichen public void eolIsSignificant(boolean flag) –Definieren, ob Zeilenende relevant ist public void quoteChar(int quoteChar) –Definieren von Anführungszeichen Zahlreiche andere Features – bitte in die Doku sehen! 48

49 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 StreamTokenizer: Anwendungsbeispiel Eine Teeliste mit der folgenden Struktur soll geparst werden: –Jeder Tee steht in einer eigenen Zeile Zeilenende ist relevant! –Die Teenamen sind durch Anführungszeichen gequotet –Hinter dem Teenamen stehen der Reihe nach Dauer des Ziehenlassens [s] Anzahl Teelöffel pro Liter Diese Einträge sind jeweils durch Leerzeichen getrennt Mittels StreamTokenizer ist das Parsen einfach! 49 "Ali Babas 40 Düfte" "Asatsuyu" 90 7 "Generic Black Tea" "Caramel" "Ceylon Pekoe" "China Jasmin" "Cool Down" "Einer für alle" "Erdbeer-Sahne" "Erfrischungskräutertee" "Früchtepfund" 420 6

50 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 StreamTokenizer: Anwendungsbeispiel public void parseTeas(Reader r) throws IOException { StreamTokenizer stok = new StreamTokenizer(r); stok.eolIsSignificant(true); // EOL melden stok.quoteChar('\"'); // " als Worttrenner int token = 0; String teaName = null; int nrSpoons, nrSecs, coolDown; while ((token = stok.nextToken()) != StreamTokenizer.TT_EOF) { teaName = stok.sval; // 1. Token token = stok.nextToken(); nrSpoons = (int)stok.nval; // 2. Token token = stok.nextToken(); nrSecs = (int)stok.nval; // 3. Token token = stok.nextToken(); // must be EOL System.out.println(teaName +":" + nrSpoons +" Loeffel, Ziehzeit: " + nrSecs); } } 50 Normalerweise sollte man vor einer Zuweisung den Typ prüfen!

51 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Scanner Seit Java 1.5 dient auch java.util.Scanner zum Parsen Scanner kann auf einem Stream, File, … geöffnet werden –Typische Anwendung: Scanner sc = new Scanner(System.in); Scanner bietet mehrere hilfreiche Methoden: –String next (); // liefert das nächste Token –x nextX (); // für x = byte, double, float, int, long, short, Line Wirft InputMismatchException falls falscher Typ gelesen –boolean hasNextX (); // Gleiches x wie oben Prüft, ob das nächste Element zu Typ X passt –Die Grenzelemente sind redefinierbar, sogar auf Worte –Auch reguläre Ausdrücke können verwendet werden Bitte schauen Sie in die API Doku für mehr Details 51

52 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T20 Was noch? Verschlüsselte Dateien, komprimierte Dateien, Dateien übers Internet,... Ausnahmen! Alle I/O Operationen sind potentielle Quelle von Ausnahmen! –Deswegen immer (siehe T16): 52 try { Befehle mit I/O } catch (IOException e) { e.printStackTrace(); }


Herunterladen ppt "Telecooperation/RBG Technische Universität Darmstadt Copyrighted material; for TUD student use only Grundlagen der Informatik 1 Thema 20: Ströme und Ein-/Ausgabe."

Ähnliche Präsentationen


Google-Anzeigen