Programmieren 2 09 File-IO Bachelor Medieninformatik Sommersemester 2015 Dipl.-Inform. Ilse Schmiedecke schmiedecke@beuth-hochschule.de 1
Eingabe und Ausgabe in Java Daten im Programm während der Ausführungszeit: Objekte Ein- und Ausgabe über die Konsole (Tastatur und Bildschirm) System.in und System.out Ein- und Ausgabe über Grafische Benutzeroberflächen (+ Maus) alles flüchtig, nach Programmende verloren 2 2
Ein- und Ausgabe persistenter Daten Über das Betriebssystem lässt sich jedes Programm dazu bringen, statt der Konsole Dateien zu benutzen: Umleitung des Eingabe- und Ausgabestroms in der Kommandozeile sehr einfach: echo eingabetext zum testen > input.txt java console.standardio < input.txt > output.txt Sehr nützlich zum Testen! 3 3
Umleiten in Ausgabedatei in Eclipse Umleitung in Eclipse über die Run Configuration nur für die Ausgabe möglich. 4 4
Standard-IO umlenken schreibt in Konsole und Datei 5 5
Ausgabe-Umlenkung verhindert Konsolen-Eingabe 6 6
Datei-IO aus dem Programm heraus Daten erreichen und verlassen ein Programm serialisiert Datenströme Datenquellen und Datensenken (oder ziele) Eingabe- und Ausgabeströme Ströme können durch Filter modifiziert werden Filter Eingabe strom Filter Ausgabe strom Datenquelle Datensenke 7 7
Datenstrom-Klassen in Java Im Paket java.io und java.nio InputStream und OutputStream sind abstrakte Klassen zum Lesen/Schreiben von Bytes (ASCII-Zeichen) Konkretisierungen sind z.b. FileInputStream und FileOutputStream Reader und Writer sind abstrakte Klassen zum Lesen / Schreiben von Unicode-Zeichen (char) InputStreamReader nimmt eine Bytestrom und liest ihn als Zeichenstrom OutputStreamWriter nimmt einen Zeichenstrom und schreibt ihn als Bytestrom BufferedInputStream/Reader/OutputStream/Writer erlauben das zeilenweise Lesen und Schreiben. LineNumberReader ist ein BufferedReader, der zusätzlich die Zeilen durchnummeriert... 8 8
Zusammenbauen von Datenströmen in Java Zeilenweise (Buffered) Zeichen lesen (Reader) aus der Konsole (InputStream): InputStream inst = System.in; Reader inrd = new InputStreamReader(inSt); BufferedReader inbuf = new BufferedReader(inRd); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); Buffered Reader Input Stream Reader System. in 9 9
Zusammenbauen von Datenströmen in Java Zeilenweise (Buffered) Zeichen schreiben(writer) in eine Textdatei (FileOutputStream): FileOutputStream outfl = new FileOutputStream("myoutput.txt"); OutputStreamWriter outwr = new OuputStreamWriter(outFl); BufferedWriter outbuf = new BufferedWriter(outWr); BufferedWriter outbuf = new BufferedWriter(new OutputStreamWriter( new FileOutputStream("myoutput.txt"))); Buffered Writer Output Stream Writer File Output Stream myoutput. txt 10 10
Zusammenbauen von Datenströmen in Java Zeilenweise (Buffered) Zeichen schreiben(writer) in eine Zeichendatei(FileWriter): FileWriter outwr = new FileWriter("myoutput.chr"); BufferedWriter outbuf = new BufferedWriter(outWr); BufferedWriter outbuf = new BufferedWriter(new FileWriter("myoutput.chr"); Buffered Writer File Writer myoutput. chr 11 11
Komfortklassen PrintStream und PrintWriter ermöglichen direkt das zeilenweise Schreiben und werfen keine Exceptions. PrintWriter writer = new PrintWriter (new FileStream("x.dat"); //Komfort-Konstruktor writer.println("dateianfang"); System.out ist vom Typ PrintStream Scanner (im Paket java.util) erlaubt direkt das zeilenweise Lesen und wirft keine Exceptions. Scanner read = new Scanner(System.in); String s = read.nextline(); 12 12
Filter in den Datenströmen Abstrakte Klassen FilterInputStream, FilterOutputStream, FilterReader, FilterWriter Eigene Implementierungen können in den Datenstrom "eingehängt" werden, z.b. Löschen von Steuerzeichen FileWriter outwr = new FileWriter("myoutput.chr"); MyFilterWriter outfilt = new MyFilterWriter(outWr); MyFilterWriter outfilt = new MyFilterWriter(new FileWriter("myoutput.chr"); MyFilter Writer File Writer myoutput. chr 13 13
Einen Filter selbst schreiben: Filter soll Groß-gegen Kleinbuchstaben tauschen und umgekehrt: FilterWriter erweitern abstrakte Klasse enthält Basis- Implementierung für alle Writer-Methoden write-methoden überschreiben Rückgriff auf Basis- Implementierung (super) in Konstruktor, für Nicht-Buchstaben und zum Schließen 14 14
Filter anwenden 15 15
Formatierte Textausgabe PrintStream und PrintWriter haben eine Methode zur formatierten Ausgabe Formatierung bedeutet auch Konvertierung von Daten: Zeit, Zahlensysteme, Rundung, etc void printf (String format, Object... args); // oder format Object... args: variable Zahl von Parametern format: Beschreibung des Formats als String: System.out.printf( "%X %3$s %2$d", 31, 31, " hexa ist "); Ausgabe: 1F hexa ist 31 Die Parameter sind indiziert 1..n, der Index kann angegeben werden (%3$ steht für den 3. Parameter) X, d, s sind Steuerzeichen (für hexadezimal mit Großbuchst., dezimal, String) Die Steuerzeichen für die Darstellung und Konvertierung findet man unter java.util.formatter 16 16
Wichtige Format-Steuerzeichen Zahlen, Zeichen Strings: d, o, x, X f, e, E, a, A g, G s, S c n Ganzzahl in Dezimal-, Oktal-, Hexadezimal und wiss. Darstellung (mit Klein- oder Großbuchstaben) Gleitpunktzahl in Dezimal-, wiss. oder Hexa-Darstellung wie e oder f nach "Bedarf" Objekt als String mittels tostring oder null Unicode-Zeichen \n plattformspez. Zeilentrenner Formatierung von Nachkommastellen Klasse java.text.decimalformat: Angabe von Stellen und Dezimalzeichen Formatstring optinal für positive und negative Wert durch ";" getrennt new DecimalFormat("#.0000") // vier Nachkommastellen new DecimalFormat("Haben #,##0.00;Soll #,##0.00") // Untersch. pos u. neg String num = new DecimalFormat("#0.00").format(1.434E2); System.out.println(num); System.out.printf("%n %s", num); 17 17
Wichtige Format-Steuerzeichen Zeit: t, T leitet Zeitkonvertierung ein H, M, S Stunde, Minute, Sekunde 2-stellig (24 h) k Stunde 1-2-stellig (0..23) L Millisekunde 3-stellig Datum B, A voller Monats- bzw. Tagesname ("Januar") b, a abgekürtzer Monats- bzw. Tagesname ("Jan") Y, y Jahr 4- bzw. 2-stellig m, d Monat, Tag 2-stellig e Monat 1-2-stellig (1-31) R Stunde und Minute im 24h-Format ("%th:%tm") T Stunde, Minute, Sekunde im 24h-Format c Standard-Format ("Fr Jan 16 14:25:08 MEZ 2015") 18 18
Arbeiten im Dateisystem Klassen für Pfade und Dateien bietet das Paket java.nio Erzeugen eines Path-Objekts - Klassen Path und Paths: Path path = Paths.get("C:\\temp\\java_test_input.txt"); Im Pfadbaum aufsteigen Path dir = path.getparent(); Umwandeln in URI URI uri = path.touri(); Kopieren, Erzeugen Löschen - Klasse Files: copy (Path source, Path target, CopyOption opt) move (Path source, Path target, CopyOption opt) ceatedirectory(path dir, FileAttribute<?> attr) createfile(path dir, FileAttribute<?> attr) delete(path path) IO-Ströme zu Pfaden new BufferedReader(Path path, Charset cs) new BufferedWriter(Path path, Charset cs, OpenOption... opt) new InputStream(Path path, Charset cs, OpenOption... opt) new OutputStream(Path path, Charset cs, OpenOption... opt) List<String> filecontent = readalllines(path path, Charset cs); 19 19
Schreiben und Lesen von Textdateien Alle bisherigen Ströme arbeiten auf der Basis von Zeichen Dateien sind lesbar Einfachste Struktur: Zeile Ein Datenwert pro Zeile Für kompliziertere Datenstrukturen braucht man Protokolle: Vereinbarungen zwischen der Schreib- und der Leseeinheit Beispiel: Schreiben und Lesen von Kontakten CSV eine übliche Form der 2-stufigen Struktur (Tabelle) 20 20
Anwendungsbeispiel: Einlesen einer CSV-Datei 21 21
Testmethode beschreibt zunächst die Eingabedatei 22 22
Protokolle Protokoll: Vereinbarung über Format und Reihenfolge der Daten Hier: CSV, getrennt durch ":" Schreib- und LeseStrom sollten aneinander angepasst sein Lese-Schreib-Paar: Prog1 CSV Writer File CSV Reader Prog2 Strom-Paar 23 23
CSVContactsWriter 24 24
Protokoll-Test Test: Schreiben, Lesen, Ausgeben 25 25
Soweit zu Textdateien Nächstes Mal gibt es Binäres... 26 26