FHZ Hochschule Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren K31 Files K31 Files • Inhalt 1. 2. 3. 4. 5. Einleitung Programmbeispiele zu binären Files Programmbeispiele zu Textfiles Weitere wichtige Klassen für das File-Handling Objekt-Serialisierung Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 1 Lernziele • Sie sind mit dem Konzept der Files in Java vertraut • Sie können Textfiles beim Einlesen in Token zerlegen • Sie kennen die Möglichkeiten für den wahlfreien zugriff auf Dateien • Sie wissen was Persistenz ist und wie der Zustand von Objekten gesichert/gelesen werden kann • Sie sind in der Lage eigene Klassen serialisierbar zu machen Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31_Files-P.ppt, V20 2004 © Diego Schmidlin K31 Files Folie 2 Seite 1 FHZ Hochschule Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren K31 Files 1. Einleitung 1.1 Unterschiede RAM vs. File ? ? ? – flüchtig vs. permanent – Zugriffszeit – Preis Hardware 1.2 Unterschiede Java-Applets vs. Java-Programme ? ? – Applets ð File-Zugriff "nicht gestattet" – Programme ð File-Zugriff gestattet 41 Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 3 1. Einleitung 1.3 File Zugriffe ? – sequentieller Zugriff ð Stream Access (vgl. Streamer-Tape, Stelle anfahren) ? – wahlfreier Zugriff ð Random Access (vgl. Array, Stelle direkt anspringen) 1.4 File-Arten ? – binäre Files ð Folge von Bytes, beliebige Daten speicherbar ? – Textfiles ð Folge von Zeichen, File mit Editor lesbar 4 1, 2 K31_Files-P.ppt, V20 2004 © Diego Schmidlin Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 4 Seite 2 FHZ Hochschule Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren K31 Files 1. Einleitung 1.5 Aufbau Textfile ? ? ? – Zeilenweise – Zeilenende markiert "\n" (Line Feed 10) – File-Ende markiert (SUB 26) 1.6 File-Bearbeitung ? ? ? – 1. open (erfolgt implizit mit new) – 2. read() oder write() – 3. close() 42 Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 5 2.1 Byte-Werte in File "data1.bin" schreiben import java.io.*; public class WriteBinaryFile1 { public static void main(String[] args) { String fileName = "data1.bin"; File aFile = new File(fileName); if (!aFile.exists()) { try { FileOutputStream aFileOutputStream = new FileOutputStream(aFile); for (int i = 0; i <= 10; i++) { aFileOutputStream.write(i); } aFileOutputStream.close(); } catch (IOException e) { System.out.println("Exception: " + e.getMessage()); return; } } } } i ð aFileOutputStream ð aFile ð data1.bin 4 3 & 15.5.2 K31_Files-P.ppt, V20 2004 © Diego Schmidlin Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 6 Seite 3 FHZ Hochschule Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren K31 Files 2.2 Byte-Werte von File "data1.bin" lesen import java.io.*; public class ReadBinaryFile1 { public static void main(String[] args) { String fileName = "data1.bin"; File aFile = new File(fileName); if (aFile.exists()) { try { FileInputStream aFileInputStream = new FileInputStream(aFile); int i = -1; // -1 means EOF (End Of File) while ((i = aFileInputStream.read()) != -1) { System.out.println(i); } aFileInputStream.close(); } catch (IOException e) { System.out.println("Exception: " + e.getMessage()); return; } } } data1.bin ð aFile ð aFileInputStream ð i } 4 4 & 15.5.2 Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 7 2.3 Datentypen in "data2.bin" schreiben import java.io.*; public class WriteBinaryFile2 { public static void main(String[] args) { String fileName = "data2.bin"; File aFile = new File(fileName); if (!aFile.exists()) { try { FileOutputStream aFileOutputStream = new FileOutputStream(aFile); // DataOutputStream allows writing values of // elementary data types. DataOutputStream aDataOutputStream = new DataOutputStream(aFileOutputStream); 4 5 & 15.6.2 K31_Files-P.ppt, V20 2004 © Diego Schmidlin Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 8 Seite 4 FHZ Hochschule Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren K31 Files 2.3 Datentypen in "data2.bin" schreiben // Number of int-values, then values ... aDataOutputStream.writeInt(3); aDataOutputStream.writeInt(1); aDataOutputStream.writeInt(2); aDataOutputStream.writeInt(3); // Number of double-values, then values ... aDataOutputStream.writeInt(2); aDataOutputStream.writeDouble(1.23456789); aDataOutputStream.writeDouble(-1.E-3); aFileOutputStream.close(); } catch (IOException e) { System.out.println("Exception: " + e.getMessage()); return; } } } } 3 ð aDataOutputStream ð aFileOutputStream ð aFile ð data2.bin 4 5 & 15.6.2 Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 9 2.4 Datentypen von "data2.bin" lesen import java.io.*; public class ReadBinaryFile2 { public static void main(String[] args) { String fileName = "data2.bin"; File aFile = new File(fileName); if (aFile.exists()) { try { FileInputStream aFileInputStream = new FileInputStream(aFile); DataInputStream aDataInputStream = new DataInputStream(aFileInputStream); int numberOfInt = aDataInputStream.readInt(); for (int i = 0; i < numberOfInt; i++) { System.out.println(aDataInputStream.readInt()); } 4 7 & 15.6.2 K31_Files-P.ppt, V20 2004 © Diego Schmidlin Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 10 Seite 5 FHZ Hochschule Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren K31 Files 2.4 Datentypen in "data2.bin" schreiben int numberOfDouble = aDataInputStream.readInt(); for (int i = 0; i < numberOfDouble; i++) { System.out.println(aDataInputStream.readDouble()); } aFileInputStream.close(); } catch (IOException e) { System.out.println("Exception: " + e.getMessage()); return; } } } } data2.bin ð aFile ð aFileInputStream ð aDataInputStream ð numberOfInt 4 7 & 15.6.2 Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 11 3.1 Text in "data1.txt" schreiben import java.io.*; import java.text.*; public class WriteTextFile1 { public static void main(String[] args) { String fileName = "data1.txt"; File aFile = new File(fileName); if (!aFile.exists()) { try { FileWriter aFileWriter = new FileWriter(aFile); BufferedWriter aBufferedWriter = new BufferedWriter(aFileWriter); PrintWriter aPrintWriter = new PrintWriter(aBufferedWriter); aPrintWriter.println("This is the 1. line."); aPrintWriter.println("This is the 2. line."); 4 8 & 15.8.4 K31_Files-P.ppt, V20 2004 © Diego Schmidlin Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 12 Seite 6 FHZ Hochschule Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren K31 Files 3.1 Text in "data1.txt" schreiben DecimalFormat df = new DecimalFormat("' '0000.000;-0000.000"); aPrintWriter.print(df.format(12.3)); aPrintWriter.print(" "); aPrintWriter.print(df.format(10)); aPrintWriter.println(); aPrintWriter.print(df.format(1111.22222)); aPrintWriter.print(" "); aPrintWriter.print(df.format(-10.1)); aPrintWriter.flush(); aFileWriter.close(); } catch (IOException e) { System.out.println("Exception: " + e.getMessage()); return; } } } } "This is the 1. line." ð aPrintWriter ð aBufferedWriter ð aFileWriter ð aFile ð data1.txt 4 9 & 15.8.4 Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 13 3.2 Text von "data1.txt" lesen public class ReadTextFile1 { public static void main(String[] args) { String fileName = "data1.txt"; File aFile = new File(fileName); if (aFile.exists()) { try { FileReader aFileReader = new FileReader(aFile); BufferedReader aBufferedReader = new BufferedReader(aFileReader); System.out.println(aBufferedReader.readLine()); System.out.println(aBufferedReader.readLine()); 4 10 & 15.8.4 K31_Files-P.ppt, V20 2004 © Diego Schmidlin Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 14 Seite 7 FHZ Hochschule Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren K31 Files 3.2 Text von "data1.txt" lesen String line; StringTokenizer sT; double d; while ((line = aBufferedReader.readLine()) != null) { sT = new StringTokenizer(line); while (sT.hasMoreTokens()) { d = (Double.valueOf( sT.nextToken())).doubleValue(); System.out.println(d); } } aFileReader.close(); } catch (IOException e) { System.out.println("Exception: " + e.getMessage()); return; } } } } data1.txt ð aFile ð aFileReader ð aBufferedReader ð readLine() 4 10 & 15.8.4 Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 15 4.1 Klasse StreamTokenizer • Klasse StreamTokenizer – Auch in Package java.io definiert – Nützliche Methoden zur lexikalischen Analyse • Groben Syntaxanalyse eines Datenstroms StreamTokenizer nval:double sval:String ttype:int commentChar(int ch):void nextToken():int ordinaryChar(int ch):void resetSyntax():void 4 12 K31_Files-P.ppt, V20 2004 © Diego Schmidlin Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 16 Seite 8 FHZ Hochschule Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren K31 Files 4.1 Klasse StreamTokenizer StreamTokenizer wird an Datenstrom angehängt • Methoden – Beschränkte Definition einer Syntax • • • • Whitespace Normale Zeichen Sonderzeichen Kommentare • Aufruf nextToken() entnimmt dem Datenstrom das nächste Token – Zeichenketten und Zahlenwerte werden automatisch in Strings bzw. double-Werte umgewandelt. 4 12 Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 17 4.1 Klasse StreamTokenizer • Beispiel – Von einem Textfile sollen, abgesehen von Kommentaren, Zeichenketten und Zahlenwerte eingelesen werden: 4 13 K31_Files-P.ppt, V20 2004 © Diego Schmidlin Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 18 Seite 9 FHZ Hochschule Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren K31 Files 4.1 Klasse StreamTokenizer import java.io.*; import java.util.StringTokenizer; public class TokenizerDemo { public static void main(String[] args) throws IOException { if (args.length == 1) { Reader aReader = new FileReader(args[0]); StreamTokenizer sT = new StreamTokenizer(aReader); sT.ordinaryChar('/'); // recognizes C++-style comments sT.slashSlashComments(true); // recognizes C-style comments sT.slashStarComments(true); // numbers should be parsed sT.parseNumbers(); // treats end of lines as tokens sT.eolIsSignificant(true); 4 13, 14 Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 19 4.1 Klasse StreamTokenizer int tval; while ((tval = sT.nextToken()) != StreamTokenizer.TT_EOF) { switch (tval) { case StreamTokenizer.TT_NUMBER : System.out.print("[N: " + sT.nval + " ]"); break; case StreamTokenizer.TT_WORD : System.out.print("[S: " + sT.sval + " ]"); break; case StreamTokenizer.TT_EOL : System.out.println(); break; default : System.out.print("[X: " + sT.ttype + " ]"); } } aReader.close(); } else { System.exit(1); } }} 4 13,14 K31_Files-P.ppt, V20 2004 © Diego Schmidlin Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 20 Seite 10 FHZ Hochschule Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren K31 Files 4.2 Klasse File • Klasse File – Hat nichts direkt mit der Ein-/Ausgabe zu tun – Stellt Betriebssystemfunktionen bereit für • Files • Verzeichnisse • Plattform unabhängig File separator:String pathSeparator:String delete():void exists():boolean getAbsolutePath():String isDirectory():boolean isFile():boolean Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 4 15 K31 Files Folie 21 4.2 Klasse File • Separatoren: – Plattformspezifische Unterschiede müssen berücksichtigt werden • Übersicht: Unix / \n : File Line Path 4 15 K31_Files-P.ppt, V20 2004 © Diego Schmidlin Separatoren Windows \ \r\n ; Macintosh : \r : Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 22 Seite 11 FHZ Hochschule Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren K31 Files 4.3 Klasse FileDialog • Klasse FileDialog – Abgeleitet von Klasse Dialog – Auswahl-Dialog für Files/ Verzeichnissen – AWT ruft plattformabhängigen Standarddialog auf Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 4 16 K31 Files Folie 23 4.3 Klasse FileDialog • Klasse FileDialog – Modaler Dialog • Eingaben in das Frame-Fenster werden unterdrückt – Bis Dialog beendet ist • Nichtmodale Dialoge ermöglichen weitere Eingaben – vgl. z.B. Rechtschreibe-Hilfe bei Word FileDialog LOAD:int SAVE:int getDirectory():String getFile():String getMode():int setFilenameFilter():void – Methode getFile() liefert den String zurück • Rückgabewert null, falls kein File selektiert wurde 4 16 K31_Files-P.ppt, V20 2004 © Diego Schmidlin Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 24 Seite 12 FHZ Hochschule Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren K31 Files 4.4 Klasse RandomAccessFile • Klasse RandomAccessFile – Ermöglicht direkten Zugriff auf beliebige Positionen innerhalb von Files RandomAccessFile close():void getFilePointer():long length():long read():int readLine():String seek(pos:long):void writeInt(v:int):void – – – – Ist nicht Unterklasse von InputStream oder OutputStream Implementiert Schnittstellen DataInput und DataOutput Besitzt gleiche Fähigkeiten wie DataInput-/DataOutputStream Mit Methode seek() kann beliebige Position im File angefahren werden 4 17 Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 25 4.4 Klasse RandomAccessFile import java.io.*; public class RandomAccessFileDemo { public static void main(String[] args) throws IOException { RandomAccessFile aRandomAccessFile = new RandomAccessFile("temp.txt", "rw"); // r = read, w = write String s = "Ein Text miit Schreibfehler."; aRandomAccessFile.seek(0); aRandomAccessFile.writeBytes(s); System.out.println("Pos: "+aRandomAccessFile.getFilePointer()); aRandomAccessFile.seek(9); aRandomAccessFile.writeBytes("ohne"); aRandomAccessFile.seek(0); System.out.println("Text: " + aRandomAccessFile.readLine()); aRandomAccessFile.close(); } } 4 18 K31_Files-P.ppt, V20 2004 © Diego Schmidlin Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 26 Seite 13 FHZ Hochschule Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren K31 Files 5. Objekt-Serialisierung • Bisherige I/O-Möglichkeiten – Elementare Datentypen: byte, char, int, String • Wunsch, Anforderung der OOP – Ein-/ Ausgabe von Objekten Objekte Werte der Instanzvariablen ObjektSerialisierung Byte-Datenstrom 4 19 & 15.9 Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 27 5. Objekt-Serialisierung • Objekt-Serialisierung – Speichern und wieder Einlesen von Objekten • Auf anderem Rechner oder via Internet • Objekte, die ausserhalb eines Laufzeitsystems existieren werden persistente Objekte genannt – Instanzvariablen werden in Byte-Datenstrom geschrieben • Marshalling/Unmarshalling – Klassenvariablen werden nicht serialisiert! ObjectOutputStream, ObjectInputStream • Ausgabestrom kann mit FileOutputStream verbunden werden 4 19 & 15.9 K31_Files-P.ppt, V20 2004 © Diego Schmidlin Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 28 Seite 14 FHZ Hochschule Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren K31 Files 5. Objekt-Serialisierung • Klassendiagramm (Ausschnitt) Object InputStream OutputStream read():int close() write() flush() close() FileInputStrea m ObjectInputStrea m FileOutputStream Obje ctOutputStream read():int close() readBoolean() readObject() write() close() writeDouble() writeObject() 4 20 & 15.9 Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 29 5. Objekt-Serialisierung • Exceptions writeObject() wirft primär folgende Exceptions: InvalidClassException NotSerializableException IOException readObject() wirft mitunter folgende Exceptions: ClassNotFoundException InvalidClassException StreamCorruptedException OptionalDataException IOException 4 20 & 15.9 K31_Files-P.ppt, V20 2004 © Diego Schmidlin Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 30 Seite 15 FHZ Hochschule Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren K31 Files 5. Objekt-Serialisierung • Modifier transient – Instanzvariablen werden nicht serialisiert • Hilfsvariablen • Sicherheitsgründe transient int currentVolume; • Interface Serializable – Klassen, die serialisiert werden sollen müssen das Interface Serializable implementieren – Leeres Interface • Marker-Interface • Erlaubt durch Überprüfung des Klassen-Typs die Serialisierung 4 21 & 15.9.2 Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 31 5. Objekt-Serialisierung import java.io.*; public class SerializationDemo { public static void main(String[] args) throws Exception { // Integer implements interface Serializable Integer i = new Integer(2000); System.out.println("i = " + i); // Write Object FileOutputStream aFileOutputStream = new FileOutputStream("temp.dat"); ObjectOutputStream aObjectOutputStream = new ObjectOutputStream(aFileOutputStream); aObjectOutputStream.writeObject(i); aFileOutputStream.close(); 4 22 K31_Files-P.ppt, V20 2004 © Diego Schmidlin Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 32 Seite 16 FHZ Hochschule Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren K31 Files 5. Objekt-Serialisierung // Read Object FileInputStream aFileInputStream = new FileInputStream("temp.dat"); ObjectInputStream aObjectInputStream = new ObjectInputStream(aFileInputStream); Object o = aObjectInputStream.readObject(); aFileInputStream.close(); Integer j = (Integer)o; System.out.println("j = " + j); } } 4 22 K31_Files-P.ppt, V20 2004 © Diego Schmidlin Abteilung Informatik, Fach Programmieren 2004 © Diego Schmidlin V20 K31 Files Folie 33 Seite 17