I/O Adrian Schüpbach [email protected] c Adrian Schüpbach Programmieren und Problemlösen – FS16 Worum geht es? I I/O (Eingabe und Ausgabe) I I I I Tastatur einlesen Kommandozeilenparameter einlesen Dateien lesen und schreiben Exceptions I I Fehlerbehandlung (Bsp.: Datei existier ev. nicht) Programmfehler Programmieren und Problemlösen – FS16 c Adrian Schüpbach 2 Exceptions Programmieren und Problemlösen – FS16 c Adrian Schüpbach 3 Exceptions I Fehler können immer passieren I Was sind Fehler? Programmieren und Problemlösen – FS16 c Adrian Schüpbach 3 Exceptions I Fehler können immer passieren I Was sind Fehler? I Verschiedene Beispiele von Fehlern I I I I I I Programmierfehler Benutzerfehler (falsche/unerwartete Eingaben) Berechnungsfehler (Division durch 0) Resource nicht vorhanden (Datei, Netzwerk, ...) Kein Speicher mehr ... Programmieren und Problemlösen – FS16 c Adrian Schüpbach 3 Exceptions I Fehler können in Klassen eingeteilt werden I I Erwartete und unerwartete Fehler Behandelbare und unbehandelbare Fehler Programmieren und Problemlösen – FS16 c Adrian Schüpbach 4 Exceptions I Fehler muss man ... 1. ... erkennen 2. ... mitteilen 3. ... behandeln I → Dafür gibt es in Java den Exception-Mechanismus Programmieren und Problemlösen – FS16 c Adrian Schüpbach 5 Exceptions I Fehler muss man ... 1. ... erkennen 2. ... mitteilen 3. ... behandeln I → Dafür gibt es in Java den Exception-Mechanismus I Man nimmt an, dass Fehler die Ausnahme sind I → Exceptions, Exception handling I Ausnahmebehandlung Programmieren und Problemlösen – FS16 c Adrian Schüpbach 5 Exceptions I Eine Exception ist ein “Fehlerobjekt” I I I I Instanz einer “Fehlerklasse” Ist wie normale Klasse in Java Beinhaltet Details über den Fehler Wenn ein Fehler eintritt, wird Fehlerobjekt erzeugt Programmieren und Problemlösen – FS16 c Adrian Schüpbach 6 Exceptions I Eine Exception ist ein “Fehlerobjekt” I I I Instanz einer “Fehlerklasse” Ist wie normale Klasse in Java Beinhaltet Details über den Fehler I Wenn ein Fehler eintritt, wird Fehlerobjekt erzeugt I Es gibt zwei Möglichkeiten, wie Fehlerobjekt erzeugt wird I System erzeugt es, wenn Fehler auftritt I I Division durch 0, ungültiger Arrayindex, ... Programmierer erzeugt Fehlerobjekt I Z.Bsp. ungültige Benutzereingabe Programmieren und Problemlösen – FS16 c Adrian Schüpbach 6 Exceptions I Sobald Exception auftritt, muss sie abgefangen werden I Normaler Programmfluss wird unterbrochen Programmieren und Problemlösen – FS16 c Adrian Schüpbach 7 Exceptions I Sobald Exception auftritt, muss sie abgefangen werden I Normaler Programmfluss wird unterbrochen I Zwei Möglichkeiten zur Behandlung I I Fehler “erwartet”: Sofort behandeln Fehler nicht erwartet: Exception an Methode weiterleiten, die “mich” aufgerufen hat Programmieren und Problemlösen – FS16 c Adrian Schüpbach 7 Exceptions Exception behandeln I I Code mit potentiellem Fehler in try-Block einbetten Exception in catch-Block behandeln I try{ } catch(Exception e) { } Programmieren und Problemlösen – FS16 c Adrian Schüpbach 8 Exceptions Exception behandeln public class Programm37 { public static void dateioeffnen ( String dateiname ){ try { // Code , der ev. Fehler haben koennte // Z.Bsp. Datei oeffnen // " Fehler " = Kann Datei nicht oeffnen } catch ( Exception e) { // Fehler behandeln // Z.Bsp. dem Benutzer sagen , dass // Datei nicht geoeffnet werden kann } } public static void main( String [] args) { dateioeffnen ("bla"); } } Programmieren und Problemlösen – FS16 c Adrian Schüpbach 9 Exceptions Exception weiterleiten I Methodensignatur zeigt an, dass Fehler weitergeleitet werden I public void m() throws Exception { } Programmieren und Problemlösen – FS16 c Adrian Schüpbach 10 Exceptions Exception nach oben weiterleiten public class Programm38 { public static void dateioeffnen ( String dateiname ) throws Exception { // Code , der ev. Fehler haben k"onnte // Z.Bsp. Datei oeffnen } public static void main( String [] args) { try { dateioeffnen ("bla"); } catch ( Exception e) { System .out. println (" Fehler "); } } } Programmieren und Problemlösen – FS16 c Adrian Schüpbach 11 Exceptions Exception erzeugen I I Exception-Objekt erzeugen (wie sonstiges Objekt auch) Exception-Objekt werfen I throw new Exception(); Programmieren und Problemlösen – FS16 c Adrian Schüpbach 12 Exceptions Exception werfen/erzeugen public class Programm39 { public static void dateioeffnen ( String dateiname ) throws Exception { if( dateiname . length () == 0) { throw new Exception (); } } public static void main( String [] args) { try { dateioeffnen ("bla"); } catch ( Exception e) { System .out. println (" Fehler "); } } } Programmieren und Problemlösen – FS16 c Adrian Schüpbach 13 Exceptions Beispiele von typischen Fehlern I Zugriff auf nicht erzeugtes Array oder Objekt I Ungültiger Array-Index I Division durch 0 I Datei nicht gefunden I ... Programmieren und Problemlösen – FS16 c Adrian Schüpbach 14 Exceptions NULL-Pointer-Exception public class Programm40 { public static void main( String [] args) { String s = null; int laenge = s. length (); int [] zahlenArray = null; zahlenArray [3] = 17; } } Programmieren und Problemlösen – FS16 c Adrian Schüpbach 15 Exceptions Besser: NULL-Pointer-Exception public class Programm41 { public static void main( String [] args) { String s = null; int laenge ; try { laenge = s. length (); } catch ( Exception e) { System .out. println (" String nicht erzeugt "); } int [] zahlenArray = null; try { zahlenArray [3] = 17; } catch ( Exception e) { System .out. println (" Array nicht erzeugt "); } Programmieren und Problemlösen – FS16 c Adrian Schüpbach 16 Exceptions Spezifische Exception fangen I I Bis jetzt gesehen: catch (Exception e) Was passiert im Folgenden Beispiel? Welche Exception? public class Programm42 { public static void main( String [] args) { String s = null; int [] zahlenArray = null; try { zahlenArray [10293] = s. length (); } catch ( Exception e) { System .out. println ("Ups , String oder Array " +" nicht erzeugt oder falsche Array - Index "); } } Programmieren und Problemlösen – FS16 c Adrian Schüpbach 17 Exceptions Spezifische Exception fangen I I Es gibt spezialisierte Exceptions Kann diese spezifisch fangen I NullPointerException I ArrayIndexOutOfBoundsException I ArithmeticException I IOException I ... Programmieren und Problemlösen – FS16 c Adrian Schüpbach 18 Exceptions Spezifische Exception fangen Spezifische Exception fangen public class Programm43 { public static void main( String [] args) { String s = null; int [] zahlenArray = null; try { zahlenArray [10293] = s. length (); } catch ( NullPointerException ne) { System .out. println (" String oder Array " +" nicht erzeugt ."); } catch ( ArrayIndexOutOfBoundsException obe) { System .out. println (" Falscher Array - Index "); } } } Programmieren und Problemlösen – FS16 c Adrian Schüpbach 19 I/O Programmieren und Problemlösen – FS16 c Adrian Schüpbach 20 I/O I I Jedes Programm liest Daten ein oder gibt Daten aus Es gibt verschiedene Eingabe- und Ausgabemöglichkeiten I I I I I I I Bildschirm Tastatur Drucker Netzwerk Dateien Kommandozeilenparameter ... Programmieren und Problemlösen – FS16 c Adrian Schüpbach 20 Tastatureingaben Programmieren und Problemlösen – FS16 c Adrian Schüpbach 21 Tastatureingaben I Tastatur ist wichtige Eingabequelle I Gehört zum System I Gibt eine Anzahl Methoden, wie Tastatur eingelesen werden kann Programmieren und Problemlösen – FS16 c Adrian Schüpbach 21 Tastatureingaben I Eingaben über String System.in.read(byte[] byteArray) I I I System liest, bis ENTER gedrückt wird Zeichen landen in Byte-Array Byte-Array in String konvertieren: String eingabe = new String(byteArray); I Achtung: Wirft IOException I try{} catch(IOException ioe) { } I IOException muss importiert werden I Mehr dazu später Programmieren und Problemlösen – FS16 c Adrian Schüpbach 22 Tastatureingaben Tastatureingabe import java.io. IOException ; public class Programm45 { public static void main( String [] args) { byte [] eingabe = new byte [256]; // SEHR WICHTIG : System .out. println ("Gib etwas ein: "); try { System .in.read( eingabe ); } catch ( IOException ieo) { System .out. println (" Eingabefehler "); } String textEingabe = new String ( eingabe ); } } Programmieren und Problemlösen – FS16 c Adrian Schüpbach 23 Kommandozeilenparameter Programmieren und Problemlösen – FS16 c Adrian Schüpbach 24 Kommandozeilenparameter I Zweite, sehr angenehme Art der Dateneingabe Programmieren und Problemlösen – FS16 c Adrian Schüpbach 24 Kommandozeilenparameter I Gesehen: public static void main(String[] args) I main nimmt also ein String-Array entgegen I Array beinhaltet einzelne Kommandozeilenparameter I Alle Parameter sind Strings, auch die Zahlen! Programmieren und Problemlösen – FS16 c Adrian Schüpbach 25 Kommandozeilenparameter I Parameter benutzen: Programm ... 1. 2. 3. 4. 5. 6. ... ... ... ... ... ... macht Schleife über ganze Parameterliste schaut sich jeden Parameter an prüft, ob er bekannt und gültig ist transformiert Text-Zahlen in echte Zahlenwerte speichert Parameterwert in Variable sollte testen, dass nötige Parameter angegeben wurden Programmieren und Problemlösen – FS16 c Adrian Schüpbach 26 Kommandozeilenparameter I Typische Kommandozeilenaufrufe I I I I java MeinProgramm -h java MeinProgramm –help java MeinProgramm -f dateiname.txt –anzahl 7 -s -l 1 java MeinProgramm -f=dateiname.txt –anzahl=7 -s -l=3 Programmieren und Problemlösen – FS16 c Adrian Schüpbach 27 Kommandozeilenparameter Kommandozeilenparameter einlesen (alle optional hier) public class Programm44 { static int level =0, anzahl =0; static boolean s=false ; static String file=""; public static void main( String [] args) { for (int i=0; i< args. length ; i++) { if (args[i]. equals ("--help")) { printUsage (); } else if (args[i]. equals ("-f")) { inputFile = args[i+1]; i++; } else if (args[i]. equals ("--anzahl ")) { anzahl = Integer . parseInt (args[i +1]); i++; } } } Programmieren und Problemlösen – FS16 c Adrian Schüpbach 28 Kommandozeilenparameter I Vorteile der Kommandozeilenparameter Programmieren und Problemlösen – FS16 c Adrian Schüpbach 29 Kommandozeilenparameter I Vorteile der Kommandozeilenparameter I Schnell für Benutzer Programmieren und Problemlösen – FS16 c Adrian Schüpbach 29 Kommandozeilenparameter I Vorteile der Kommandozeilenparameter I I Schnell für Benutzer Kann aus Skript/Programm mit Parametern aufgerufen werden Programmieren und Problemlösen – FS16 c Adrian Schüpbach 29 Kommandozeilenparameter I Vorteile der Kommandozeilenparameter I I I Schnell für Benutzer Kann aus Skript/Programm mit Parametern aufgerufen werden Einfach, gewisse Eingaben optional zu machen Programmieren und Problemlösen – FS16 c Adrian Schüpbach 29 Dateien Programmieren und Problemlösen – FS16 c Adrian Schüpbach 30 Dateien I Dateien: Datenspeicher Programmieren und Problemlösen – FS16 c Adrian Schüpbach 30 Dateien I Dateien: Datenspeicher I Eigenschaften I I I Grosse Datenmenge (Ein- und Ausgabe) Aneinanderkettung von Bytes Daten bleiben bestehen → Persistenz Programmieren und Problemlösen – FS16 c Adrian Schüpbach 30 Dateien I Solange Inhalt der Datei nicht intepretiert wird, sind es nur Bytes Programmieren und Problemlösen – FS16 c Adrian Schüpbach 31 Dateien I Solange Inhalt der Datei nicht intepretiert wird, sind es nur Bytes I Dateiformate I I Dateiformate erklären, wie Inhalt interpretiert werden soll Bsp.: CSV, Bild, HTML, Zip, PDF, ... Programmieren und Problemlösen – FS16 c Adrian Schüpbach 31 Dateien I Solange Inhalt der Datei nicht intepretiert wird, sind es nur Bytes I Dateiformate I I I Dateiformate erklären, wie Inhalt interpretiert werden soll Bsp.: CSV, Bild, HTML, Zip, PDF, ... Bsp.: CSV: Tabelle, Spalten mit Komma getrennt I I I Datei soll zeilenweise eingelesen werden Komma trennt Spalten Text zwischen Kommas ist Zelleninhalt Programmieren und Problemlösen – FS16 c Adrian Schüpbach 31 Dateien I Wichtige Klassen im Umgang mit Dateien: I File I FileReader I FileWriter I BufferedReader I BufferedWriter I RandomAccessFile Programmieren und Problemlösen – FS16 c Adrian Schüpbach 32 Dateien File I File ist allgemeines Datei-Objekt I Informationen über Dateien I Datei erzeugen I Datei löschen I File-Objekt erzeugen I File datei = new File("dateiname.txt"); I Erzeugt File-Objekt, nicht Datei! Programmieren und Problemlösen – FS16 c Adrian Schüpbach 33 Dateien File Nützlichen File-Funktionen Anweisung File f=new File("datei.txt"); boolean b = f.exists() long l = f.length(); f.createNewFile(); f.delete(); f.isFile() Programmieren und Problemlösen – FS16 Operation Erzeugt neues File-Objekt Testet, ob Datei existiert Gibt Dateigrösse zurück Erzeugt Datei mit Namen in f Löscht die Datei Abfrage, ob Pfad Datei ist c Adrian Schüpbach 34 Dateien File Pfade Anweisung File f=new File("././datei.txt"); String s=f.getName(); String s=f.getPath(); String s=f.getAbsolutePath(); String s=f.getCanonicalPath(); Programmieren und Problemlösen – FS16 c Adrian Schüpbach Operation Erzeugt neues File-Objekt dateiname.txt ././dateiname.txt /home/adrian/programm/ java/././dateiname.txt /home/adrian/programm/ java/dateiname.txt 35 Dateien File I Komplette Liste der Methoden der Klasse java.io.File in der API erklärt. Programmieren und Problemlösen – FS16 c Adrian Schüpbach 36 Dateien File File public class Programm46 { public static void main( String [] args) throws IOException { File f = new File(" testdatei01 .txt"); if (!f. exists ()) { f. createNewFile (); } String canonicalName = f. getCanonicalPath (); long dateiGroesse = f. length (); System .out. println (" Datei " + canonicalName + " ist " + dateiGroesse + " Bytes gross ."); f. delete (); } } Programmieren und Problemlösen – FS16 c Adrian Schüpbach 37 Dateien Programmieren und Problemlösen – FS16 c Adrian Schüpbach 38 Dateien I Dateien einlesen Programmieren und Problemlösen – FS16 c Adrian Schüpbach 38 Dateien I Dateien einlesen I Vorgehensweise/“Lesealgorithmus” 1. Datei öffnen 2. Datei einlesen 3. Datei schliessen Programmieren und Problemlösen – FS16 c Adrian Schüpbach 38 Dateien Lesezeiger I Datei hat Lesezeiger I I I Zeigt auf nächstes Byte, das eingelesen wird Zeigt direkt nach dem Öffnen auf Byte 0 (erstes Byte) Wird automatisch um 1 erhöht, nachdem ein Byte gelesen wurde Programmieren und Problemlösen – FS16 c Adrian Schüpbach 39 Dateien FileReader I FileReader verantwortlich ... I ... eine Datei zu öffnen I ... eine Datei einzulesen I ... eine Datei zu schliessen I ... Lesezeigermanipulationen Programmieren und Problemlösen – FS16 c Adrian Schüpbach 40 Dateien FileReader Nützlichen FileReader-Funktionen Anweisung FileReader fr = new FileReader(File f) FileReader fr = new FileReader(String dateiName) fr.close() fr.read(char[] buffer) fr.skip(long n) Programmieren und Problemlösen – FS16 c Adrian Schüpbach Operation Öffnet Datei Öffnet Datei Schliesst Datei Liest Bytes in Buffer ein Lässt n Bytes aus 41 Dateien FileReader I Kleine Dateien komplett einlesen 1. 2. 3. 4. Dateigrösse bestimmen Puffer dieser Grösse allozieren Datei einlesen Datei schliessen Programmieren und Problemlösen – FS16 c Adrian Schüpbach 42 Dateien FileReader I Kleine Dateien komplett einlesen 1. 2. 3. 4. I I Dateigrösse bestimmen Puffer dieser Grösse allozieren Datei einlesen Datei schliessen Grosse Dateien können kaum komplett eingelesen werden Müssen Blockweise/Zeilenweise eingelesen werden 1. 2. 3. 4. Puffer einer fixen Grösse allozieren Schleife implementieren In jedem Schleifendurchgang Block lesen Datei schliessen Programmieren und Problemlösen – FS16 c Adrian Schüpbach 42 Dateien FileReader Datei blockweise lesen public class Programm47 { public static void main( String [] args) throws Exception { FileReader fr = new FileReader (" datei .txt"); char [] puffer = new char [1024]; while (fr.read( puffer ) != -1) { String s = new String ( puffer ); System .out. println (" Naechtser Teil: " + s); } fr. close (); } } Programmieren und Problemlösen – FS16 c Adrian Schüpbach 43 Dateien Textdatei einlesen Programmieren und Problemlösen – FS16 c Adrian Schüpbach 44 Dateien Textdatei einlesen I Oft speichern Dateien Text I I Auch Zahlen in Textform Oft sind Tabellen in Textform gespeichert I I Eine Zeile in der Datei = Eine Zeile der Tabelle Komma trennt Spalten Programmieren und Problemlösen – FS16 c Adrian Schüpbach 44 Dateien Textdatei einlesen I Oft speichern Dateien Text I I I I I Auch Zahlen in Textform Oft sind Tabellen in Textform gespeichert Eine Zeile in der Datei = Eine Zeile der Tabelle Komma trennt Spalten Idealerweise zeilenweise einlesen Programmieren und Problemlösen – FS16 c Adrian Schüpbach 44 Dateien Textdatei einlesen I BufferedReader hat Methode String readLine() I Liest eine ganze Zeile I Gibt den String zurück I String hat Methode split(char trennung) I String wird in mehrere Strings eingeteilt I Trennungszeichen wird in char trennung angegeben I → Kombination liefert I I Zeile Auftrennung in Spalten Programmieren und Problemlösen – FS16 c Adrian Schüpbach 45 Dateien Textdatei einlesen Datei zeilenweise einlesen public class Programm48 { public static void main( String [] args) throws Exception { FileReader fr = new FileReader (" datei .txt"); BufferedReader reader = new BufferedReader (fr ); String zeile ; while (( zeile = reader . readLine ()) != null) { String [] spalten = zeile . split (","); int zahl = Integer . parseInt ( spalten [3]); } } } Programmieren und Problemlösen – FS16 c Adrian Schüpbach 46 Dateien Textdatei schreiben Programmieren und Problemlösen – FS16 c Adrian Schüpbach 47 Dateien Textdatei schreiben I Dateien schreiben Programmieren und Problemlösen – FS16 c Adrian Schüpbach 47 Dateien Textdatei schreiben I Dateien schreiben I “Speichern” == in eine Datei schreiben I I I Daten Einstellungen ... Programmieren und Problemlösen – FS16 c Adrian Schüpbach 47 Dateien Textdatei schreiben I Algorithmus 1. Datei erstellen oder existierende Datei öffnen 2. Daten schreiben 3. Datei schliessen Programmieren und Problemlösen – FS16 c Adrian Schüpbach 48 Dateien Textdatei schreiben I Algorithmus 1. Datei erstellen oder existierende Datei öffnen 2. Daten schreiben 3. Datei schliessen I → ähnlich, wie Datei lesen Programmieren und Problemlösen – FS16 c Adrian Schüpbach 48 Dateien Textdatei schreiben I Kombination aus FileWriter und BufferedWriter I So wie FileReader und BufferedReader Programmieren und Problemlösen – FS16 c Adrian Schüpbach 49 Dateien Textdatei schreiben Nützlichen BufferedWriter-Funktionen Anweisung BufferedWriter bw = new BufferedWriter(fileWriter) bw.close() bw.newLine() bw.write(String s, int off, int len) Programmieren und Problemlösen – FS16 Operation Öffnet Datei Schliesst Datei Fügt Zeichen für eine neue Zeile ein Schreibt Teil eines Strings c Adrian Schüpbach 50 Dateien Textdatei schreiben Textdatei schreiben public class Programm49 { public static void main( String [] args) throws Exception { File file = new File(" datei .txt"); file. createNewFile (); BufferedWriter bw = new BufferedWriter (new FileWriter (file )); String text1 = "Welt"; String text2 = "All"; bw. write (text1 , 0, text1 . length ()); bw. newLine (); bw. write (text2 , 0, text2 . length ()); bw. close (); } } Programmieren und Problemlösen – FS16 c Adrian Schüpbach 51 Dateien Programmieren und Problemlösen – FS16 c Adrian Schüpbach 52 Dateien I Jetzt können wir ... I I I I I ... ... ... ... Dateien erstellen Dateien löschen Dateien vollständig einlesen Dateien vollständig schreiben → Super für Bearbeitung wissenschaftlicher Daten Programmieren und Problemlösen – FS16 c Adrian Schüpbach 52 Dateien I Jetzt können wir ... I I I I ... ... ... ... Dateien erstellen Dateien löschen Dateien vollständig einlesen Dateien vollständig schreiben I → Super für Bearbeitung wissenschaftlicher Daten I Manchmal Daten aus Datei von bestimmter Stelle lesen I Manchmal in Datei an bestimmte Stelle schreiben Programmieren und Problemlösen – FS16 c Adrian Schüpbach 52 Dateien I Jetzt können wir ... I I I I ... ... ... ... Dateien erstellen Dateien löschen Dateien vollständig einlesen Dateien vollständig schreiben I → Super für Bearbeitung wissenschaftlicher Daten I Manchmal Daten aus Datei von bestimmter Stelle lesen I Manchmal in Datei an bestimmte Stelle schreiben I → RandomAccessFile Programmieren und Problemlösen – FS16 c Adrian Schüpbach 52 Dateien RandomAccessFile I Methode seek(long pos) I I I Setzt Dateizeiger auf Position pos Nächste Lese- oder Schreiboperation beginnt an Stelle pos Ausserdem grosse Methodensammlung für Lese- und Schreiboperationen Programmieren und Problemlösen – FS16 c Adrian Schüpbach 53 Dateien RandomAccessFile Nützlichen RandomAccessFile-Funktionen Anweisung RandomAccessFile raf = new RandomAccessFile(String name, String mode) RandomAccessFile raf = new RandomAccessFile(File file, String mode) raf.close() Programmieren und Problemlösen – FS16 c Adrian Schüpbach Operation Öffnet Datei Öffnet Datei Schliesst Datei 54 Dateien RandomAccessFile Nützlichen RandomAccessFile-Funktionen Anweisung raf.seek(long pos) raf.readInt() raf.readLine() raf.writeDouble(double d) ... Operation Setzt Dateizeiger auf pos Liest Integer Liest Textzeile Schreibt double ... Um eine so geschrieben Datei richtig einlesen zu können, muss man das Dateiformat genaustens kennen! Programmieren und Problemlösen – FS16 c Adrian Schüpbach 55