Java-AG Datenstreams: Dateibehandlung, Lesen aus und schreiben in eine Datei.

Post on 06-Apr-2016

225 views 0 download

transcript

Java-AG

Datenstreams: Dateibehandlung,

Lesen aus und schreiben in eine Datei

Übersicht

• Was sind Datenstreams?• Lesen von Daten• Schreiben von Daten• Rückblick „Fehlerbehandlung“

Was sind Datenstreams?• Kommunikationpfad zwischen Quelle

und Ziel eines Informationsblocks• Informationsblock selbst bleibt

zunächst uninterpretiert, daher beliebige Zeichenfolge möglich

• Einfachstes Beispiel: Array im Speicher• Wichtigste Anwendung: Zugriff auf

Dateien

Verwendung von Datenstreams

• alle Klassen (sowohl zum Lesen als auch zum Schreiben von Daten) benötigen das Paket java.io; es sollte daher am Anfang des Programms importiert werden:

import java.io.*;

Verwendung von Datenstreams

• wenn Dateien über das Internet angesprochen werden sollen, wird die Klasse URL benötigt, sie liegt im Paket java.net, das gegebenenfalls importiert importiert werden muß:

import java.net.*;

Lesen von Dateien

• Generell erfolgt das Lesen von Byte-Streams durch zwei abstrakte Klassen: Reader und InputStream

• Methoden bei Reader und InputStream im wesentlichen gleich

Methoden zum Lesen von Dateien

• InputStream liefert eine Folge von Bytes (byte), dabei liegt der Zeichencode „Unicode“ (16 bit pro Zeichen) zugrunde

• Reader liest eine Folge von Zeichen (char), hierbei wird der Zeichensatz des Rechnersystems genutzt (z.B. ISO-8859-1 in Westeuropa)

Methoden zum Lesen von Dateien

• wichtigste Methode zum Lesen: read ()

• Parameter: Ziel, Offset, Länger.read(cbuffer, 100, 200);

liest aus dem Objekt cbuffer die Zeichen 100 bis 299

Weitere Methoden zum Lesen von Dateien

• Überspringen von Zeichen:skip (long)

• Status des Datenstreams abfragen: ready ()

• Länge des Streams bestimmen: available ()

Weitere Methoden zum Lesen von Dateien

• Nach Ende des Lesevorgangs Stream schließen, um die Nutzung der Quelle durch andere Ressourcen zu ermöglichen:

close ()

Lesen aus einem Array

• Zu verwendende Variante abhängig vom gewünschten Datentyp:

ByteArrayInputStream ()

CharArrayReader ()

BufferedInputStream• Steigerung der Effizienz durch

Vermeidung unnötiges Hardware-Zugriffe:

• new BufferedInputStream (Ziel)für einen Puffer mit Standardgröße

• mit (Ziel, int) kann die Größe des Puffers angepaßt werden

Spezielle Input-Streams

• Lesen von Daten aus binären Datenfiles:

new DataInputStream (Ziel)• Interessant: die speziellen Methoden

boolean readBoolean(), byte readByte(), float readFloat(), usw.

ObjectInputStream• Lesen von Objekten mit ObjectInputStream

• Methoden analog zu DataInputStream, zusätzlich

Object readObject()für Objekte• Diese müssen allerdings in den

richtigen Typ umgewandelt werden, z.B.

d = (Date) in.readObject();

Lesen vom Web-Server

• Zugriff durch Klasse URL:URL url;try {url = new url („http....“);in =new BufferedInputStream (url.openStream() );....} catch ...

OutputStream

• Öffnen des OutputStreams:new FileOutputStream

(filename, true/false);• zusätzliche Option Appendmode

(true/false) ab JDK 1.1, wobei false eine neue Datei erzeugt und true die Informationen an eine bereits existierende Datei anhängt

Methoden des OutputStreams

• write(int); schreibt ein Byte mit angegebenem Wert

• write(byte[]); write(byte[], offset, length);schreibt alle im byte-Array bzw. im Teilbereich des byte-Array enthaltenen Bytes

Methoden des OutputStreams

• flush()sorgt dafür, daß alle eventuell noch im Puffer wartenden Bytes tatsächlich in die Datei geschrieben werden

• Sollte immer vor close()

oder einem Abbruch des Programms aufgerufen werden

Spezielle OutputStreams• BufferedOutputStream (Ziel)

funktioniert analog zu BufferedInputStream.

Auch hier ist die Angabe der Puffergröße als int möglich.

Spezielle OutputStreams• DataOutputStream (Ziel)

zum Schreiben von binären Datenfiles• Plattformunabhängig• Daten für DataInputStream nutzbar• Methoden:

writeBoolean(boolean); writeByte(int); writeBytes(String); etc.

Spezielle OutputStreams• ObjectOutputStream (Ziel)

wie DataOutputStream, zusätzlich writeObject(Object)

• Auch hier: Object ist Superklasse für alle Klassen, Object kann also beliebig sein

• Bsp: Date d; ...Out.writeObject(d);

Writer• Analog zu FileReader, BufferedReader, und InputStreamReader existieren FileWriter, BufferedWriter und OutputStreamWriter

• PrintWriter enthält zusätzlich Methoden zur Umwandlung von Zahlen und Objekten für print und println

RandomAccessFile• RandomAccessFiles erlauben neben

den üblichen Stream-Methoden (read, write, flush, close) auch das „Springen“ an bestimmte Stellen innerhalb des Files.

RandomAccessFile• long getFilePoint()

liefert die aktuelle Position während des Lesens/Schreibens innerhalb des Files

• long lenght() Liefert die Länge des Files

• seek (long) setzt den FilePointer auf eine bestimmte Stelle für das nächste read oder write

Exceptions

• alle Fehler bei Dateizugriffen sollten mit

try {...}catch {...}finally {Streamname.close()}

abgefangen werden, um Probleme bei späteren Dateizugriffen zu vermeiden

EOFException• Fast alle read-Methoden werfen am

Ende des Files ein EOFException aus:try {while (true) {..Streamname.read..}catch {EOFException e}finally {Streamname.close()}

Exceptions• auch beim Erzeugen des Datenstreams

sollte man auf Nummer sicher gehen:Reader r =

tryToMakeNewReader ();if (r != null)

try {...}catch {...}finally {r.close()}

Aufgabe Schreibt ein kurzes Programm, daß die Datei index.html im

Verzeichnis/HOWTO/HOWTO-INDEX auf dem HTTP-Server www.linuxdoc.org einliest.

LösungZunächst werden die Pakete importiert:import java.io.*;import java.net.*;

Danach werden die Variablen deklariert:URL url;RandomAccessFile einlesen;

Lösung (2)In der äußeren TRY/CATCH-Anweisung wird dieZieladresse geöffnet:try {url = new url(„http://www.linuxdoc.org/HOWTO/HOWTO-INDEX/index.html“);

Dann wird der Datenstrom geöffnet:einlesen = new RandomAccessFile(url.openStream() );

Lösung (3)Die innere TRY/CATCH-Anweisung schütztden eigentlichen Lese-Vorgang:try {while (true){einlesen.read()}

}Fehler werden abgefangen, in jedem Fall wird der Lese-Vorgang abgeschlossen:catch (EOFException e) {System.out.println("error "+e) }finally {einlesen.close()} }

Lösung (4)Jetzt wird noch die äußere CATCH-

Anweisungausgewertet und zu Ende gebracht:catch (Exception e) {System.out.println("error "+e);}Und der Datenstrom geschlossen:finally {url.closestream()};