Folien, pdf

Werbung
Info B VL 7: Input/Output
Objektorientiere Programmierung in Java
2003
Ute Schmid (Vorlesung)
Elmar Ludwig (Übung)
FB Mathematik/Informatik, Universität Osnabrück
Info B VL 7: Input/Output – p.174
Exkurs: Design Patterns
siehe Cooper, Java Design Patterns
Abstrakter Code, Schema, das wiederverwendet
werden kann
Beispiel: Factory-Pattern
X
XFactory
+XFactory()
+do_X()
+newObj() : X
XY
XZ
...
+do_X()
+do_X()
Info B VL 7: Input/Output – p.175
Eingabe-/Ausgabeströme (1)
open a stream
while more information
read information
close the stream
open a stream
while more information
write information
close the stream
Info B VL 7: Input/Output – p.176
Eingabe-/Ausgabeströme (2)
Einlesen von Information aus externer Quelle (source):
Tastatur, Datei, Speicher, anderes Programm, Internet,
...
Ausgabe von Information zu externer Destination
(sink): Bildschirm, Datei, Drucker, Speicher, anderes
Programm, Internet, ...
Information: Zeichen, Objekte, Bilder
Verarbeitung immer sequentiell!
Info B VL 7: Input/Output – p.177
Struktur von ‘java.io’ (1)
Reader
Abstrakte Klassen zum Lesen und Schreiben
von Character−Strömen
Writer
InputStream
Abstrakte Klassen zum Lesen und Schreiben
von Byte−Strömen
Object
OutputStream
RandomAccessFile
Lesen und Schreiben an beliebigen Stellen
in einer Datei
StreamTokenizer
Zerlegung von Input in Tokens
File
Plattform−unabhängige Definition von Datei− und
Verzeichnisnamen
<<interface>>
Serializable
<<interface>>
Externizable
Info B VL 7: Input/Output – p.178
Struktur von ‘java.io’ (2)
auf “oberster Ebene”:
Abstrakte Klassen zum Lesen/Schreiben von Charund Byte-Strömen:
Reader/Writer (Chars),
InputStream/OutputStream (Bytes)
RandomAccessFile: Lesen und Schreiben von
Bytes/Text/primitiven Typen von/in spezifische Position
einer Datei
StreamTokenizer: Zerlegung des Eingebestroms in
Tokenns (einfache lexikalische Analyse)
File: BS-unabhängige Repräsentation von Datei- und
Pfadnamen. File-Objekt bezeichnet den Dateistrom
aus/in den gelesen/geschrieben werden kann.
Methoden zum Listem von Verzeichnissen, Pruefen
von Rechten etc.
Info B VL 7: Input/Output – p.179
File implementiert das Serializable-Interface
Character und Byte Ströme
Lesen/Schreiben von 16-Bit (unicode) Zeichen:
Abstrakte Reader/Writer Klasse und entsprechende
Unterklassen (ab Java 1.1).
Lesen/Schreiben von 8-Bit Bytes: Abstrakte
InputStream/OutputStream Klasse und
entsprechende Unterklassen (ab Java 1.0).
Ähnliche APIs (Methoden mit gleichem Namen und
äquivalenter Signatur) für verschiedene Character- und
Byte-Ströme.
Für Byte-Ströme werden Byte-Arrays, für
Character-Ströme Character-Arrays verarbeitet.
Info B VL 7: Input/Output – p.180
‘read’ und ‘write’ (1)
int read()
int read(char cbuf[])
int read(char cbuf[], int offset, int length)
int write(int c)
int write(char cbuf[])
int write(char cbuf[], int offset, int length)
read() und write() können IOExceptions
werfen.
Überladene Methoden:
Lesen/Schreiben eines Zeichens/Bytes.
Lesen/Schreiben in/aus Array von Zeichen/Bytes.
Lesen/Schreiben von length Zeichen/Bytes
in/aus Array ab Index offset.
Info B VL 7: Input/Output – p.181
‘read’ und ‘write’ (2)
read() liefert int zurück:
255 für Bytes oder
0
65535 (0x00-0xffff) für Characters und
0
-1 für Ende des Stroms.
Bei den Methoden, die Arrays verarbeiten, wird die
Anzahl der verarbeiteten Zeichen/Bytes zurückgeliefert
bzw. -1 für Ede des Stroms.
Info B VL 7: Input/Output – p.182
‘Reader’ und ‘Writer’ (1)
InputStreamReader
Reader
FileReader
BufferedReader
FileInputStream
FilterReader
OutputStreamReader
Writer
BufferedWriter
FilterWriter
BufferedInputStream
InputStream
FilterInputStream
FileWriter
FileOutputStream
OutputStream
BufferedOutputStream
FilterOutputStream
Info B VL 7: Input/Output – p.183
‘Reader’ und ‘Writer’ (2)
Um komplexe Funktionalität zu erhalten, werden
gerade im I/O-Bereich häufig Objekte
komponiert/ineinander verschachtelt.
Viele Konstruktoren und Methoden in java.io werfen
Exceptions!
Die Klasse InputStreamReader bietet eine
Reader-Schnittstelle zu einem InputStream (analog
für OutputStreamWriter): ein
InputStream-Objekt wird in ein
InputStreamReader-Objekt eingebettet.
public class InputStreamReader extends Reader {
public InputStreamReader(java.io.InputStream in);
// ...
}
Info B VL 7: Input/Output – p.184
‘Reader’ und ‘Writer’ (3)
Schreiben in eine Datei und Lesen aus einer Datei
kann mit FileWriter und FileReader erledigt
werden.
Die Angabe von Dateien kann über File-Objekte oder
(plattform-spezifische) Dateinamen als Strings
erfolgen. Konstruktoren:
public class FileReader extends InputStreamReader {
// public constructor
public FileReader(File file)
throws FileNotFoundException;
public FileReader(String fileName)
throws FileNotFoundException;
// ...
}
Info B VL 7: Input/Output – p.185
‘Reader’ und ‘Writer’ (4)
Puffern von Daten bringt Effizienz: Daten werden (in
Array) gesammelt und dann weiterverarbeitet. Die
Klasse BufferedReader hat eine
readLine()-Methode.
Die abstrakten Filter-Klassen FilterReader und
FilterWriter erlauben Zusatzfunktionen während
des Lesens/Schreibens: z.B. Zählen von Zeichen,
Umwandlung von Zeichen etc.
Info B VL 7: Input/Output – p.186
Datei Ströme (1)
Beispielcode: Copy.java
Klasse File: Konstruktor erzeugt File-Objekt aus
String.
Achtung bei Pfadnamen: Pfadseparatoren sind vom
Betriebssystem abhängig
Dateiname kann direkt als String an FileReader
übergeben werden, z. B.
FileReader(farrago.txt");
FileReader ist ein Datei-Strom.
FileReader ist Unterklasse von
InputStreamReader: Eine Datei ist eigentlich als
Folge von Bytes und nicht von Unicode-Zeichen
repräsentiert. Die Klasse FileReader realisiert die
Anwendung eines InputStreamReader auf ein
InputStream-Objekt!
Info B VL 7: Input/Output – p.187
Datei Ströme (2)
mit new FileReader(...) etc. wird die Datei
automatisch geöffnet.
Dateien können (sollten) explizit geschlossen werden,
damit keine Ausgabe im I/O-Puffer verbleibt (flush). Im
Prinzip werden Dateien auch vom Garbage Collector
geschlossen, wenn nicht mehr auf sie zugegriffen wird.
In dem Programm könnte noch eine Abfrage eingebaut
werden, ob der Name der Zieldatei verschieden vom
Namen der Quelldatei ist (equals() Methode der
Klasse File).
Info B VL 7: Input/Output – p.188
Puffern von Daten
Beispielcode: BufferDemo.java
Beliebige Reader-Objekte können in einen
BufferedReader gesteckt werden, also z.B.
FileReader-Objekte. (analog für Writer, analog für
Byte-Ströme)
System.in ist ein InputStream-Objekt!
Analog zu BufferedReader in =
new BufferedReader(new FileReader(inputFile));
kann natürlich geschrieben werden:
FileReader fr = new FileReader(inputFile);
BufferedReader in = new BufferedReader(fr);
Achtung: bei gepufferten Ausgabe-Strömen muss
flush() angewendet werden, damit der Puffer
“geleert”, also damit wirklich geschrieben wird.
close() führt automatisch ein flushing aus. Info B VL 7: Input/Output – p.189
Filter Ströme (1)
Die abstrakten Filter-Klassen von java.io erlauben
es, beim Lesen und Schreiben zusätzliche
Operationen durchzuführen.
Die default-Implementation der Filter-Klassen leiten die
Methodenaufrufe an das bei Konstruktion übergebene
Objekt weiter, z.B. übliches read(): Null-Filter.
Wird eine Unterklasse einer Filter-Klasse wie
FilterInputStream definiert, so können genau die
Methoden überschrieben werden, von denen man
zusätzliche Funktionalität haben möchte.
Die Filter-Klassen entsprechen dem
Decorator-Pattern. Der Name kommt ursprünglich aus
der GUI-Programmierung (z.B. Fenster mit
verschiedener Dekoration), ist aber analog für
nicht-visuelle Bereiche definiert.
Info B VL 7: Input/Output – p.190
Filter Ströme (2)
Beispielcode: CaseFilter.java, DecoStream.java
Die CaseFilter-Klasse implementiert eine erweiterte
Funktionalität für read(): Beim Einlesen werden
Kleinbuchstaben in Grossbuchstaben umgewandelt.
In der Klasse DecoStream wird nun das read()
eines CaseFilter-Objekts verwendet. Direkt beim
Einlesen wird der Text nun umformatiert!
Vergleiche String und + vs. StringBuffer und
append().
Info B VL 7: Input/Output – p.191
Standard IO (1)
Auf Betriebssystem-Ebene existieren für jedes
laufende Programm drei Ströme: Standard Input,
Standard Output und Standard Error.
In Java existieren entsprechende Objekte in der
System-Klasse:
System.in: ist ein InputStream
System.out und Systen.err sind bereits in
einen PrintStream gepackt (statt
OutputStream).
Defaultmässig ist Standard Input die Tastatur,
Standard Output und Error der Monitor.
Die Defaults können über das Betriebssystem, aber
auch innerhalb eines Programms (z.B. Java)
umdefiniert werden.
Info B VL 7: Input/Output – p.192
Standard IO (2)
Statische Methoden in der System-Klasse und die
Default-Belegung:
setIn(InputStream in)
setOut(PrintStream out)
setErr(PrintStream err)
Im Programmbeispiel BufferDemo wurde gezeigt, wie
ein System.in-Objekt in ein Reader-Objekt und
dann in ein BufferedReader-Objekt gepackt werden
kann.
Bereits bekannt ist die Verwendung der Methoden
System.out.print() und
System.out.println().
Beispiecode: Redirecting.java
Info B VL 7: Input/Output – p.193
IO Exceptions
CharConversionException
EOFException
java.lang
java.io
InvalidClassException
FileNotFoundException
InvalidObjectException
Exception
IOException
InterruptedIOException
NotActiveException
ObjectStreamException
NotSerializableException
SyncFailedException
OptionalDataException
UnsupportedEncodingException
StreamCorruptedException
UTFDataFormatException
WriteAbortedException
Info B VL 7: Input/Output – p.194
Random Access
RandomAccessFile stammt direkt von Object ab
und implementiert die Interfaces DataInput und
DataOutput.
Die Klasse ermöglicht Lesen und Schreiben sowie das
Vorwärts- und Rückwärtsgehen in einer Datei.
Sie kann nicht in einen BufferedInputStream o.Ä.
gepackt werden.
Im Prinzip arbeitet die Klasse wie ein kombinierter
DataInputStream und DataOutputStream.
Typische Anwendung: Effizientes Lesen aus
ZIP-Archiv
Info B VL 7: Input/Output – p.195
Sequentieller Zugriff
Öffnen des ZIP-Archivs
Sequentielle Suche bis das gewünschte File gefunden
ist
Extraktion des Files
Schliessen des ZIP-Archivs
Aufwand: im Mittel halbe Länge des ZIP-Files
Info B VL 7: Input/Output – p.196
Random Access
Öffnen des ZIP-Archivs
Suche des dir-entry und lokalisiere den Eintrag für
das gewünschte File
Suche rückwärts zur Position des Files
Extraktion des Files
Schliessen des ZIP-Archivs
Info B VL 7: Input/Output – p.197
Weitere Aspekte
StreamTokenizer
Serializable
Pipe-Ströme
Info B VL 7: Input/Output – p.198
Herunterladen