Wie arbeitet man mit Datenströmen?
Die Byte-orientierten Ströme sind von den abstrakten
Klassen InputStream
und OutputStream
,
die Zeichen-orientierten Ströme von den ebenfalls
abstrakten Klassen Reader
und Writer
abgeleitet.
Der allgemeine Umgang mit Datenströmen sei hier
beispielhaft an einem DataInputStream
erläutert. Er liest primitive Daten von einem zugrunde
liegenden InputStream
, hier mittels eines FileInputStream
,
der Methoden zum Auslesen von Datein bereitstellt. Die
geschachtelte Verwendung zweier Ströme, ist in Java
verbreitet. Ein erster Stream liest die Rohdaten aus der
jeweiligen ggf. Maschinen- und Betriebssystem-abhängigen
Quelle und reicht sie weiter zu einer spezifischeren Auswertung,
die durch eine Reihe spezialisierter Streams erfolgt (s.u.).
Diese besitzen Methoden zur adäquaten
Handhabung der jeweiligen Daten.
DataInputStream in = null; int i; try { in = new DataInputStream(new FileInputStream("test.txt")); while ((i = in.read()) != -1) System.out.print(i); } catch (IOException e) { e.printStackTrace(); } finally { try { if (in != null) in.close(); } catch (IOException ioe) {} }
Bei der Verarbeitung von Streams können je nach Art des
Stroms mannigfaltige Fehler auftreten: Die zu lesende Datei kann
nicht gefunden werden, beim Auslesen können Probleme
auftreten, der Speicherplatz kann zu Ende gehen, etc. Diese
möglichen Fehler müssen gesichert abgefangen werden.
Dies geschieht in einem try-catch-Block. In seinem finally
-Abschnitt
ist dieser zudem für ein geordnetes Schließen des
Stroms verantwortlich, da er auf jeden Fall ausgeführt
wird, unabhängig davon, ob die Anweisungen im try
-Block
erfolgreich ausgeführt werden konnten oder nicht.
Da
beim Schließen des Stroms durch die Methode close()
wiederum eine IOException
geworfen werden kann,
muss hier nochmals ein try-catch
-Block eingesetzt
werden.
try-with-resources Statement
7.0Wie deutlich erkennbar, so
führt diese Konstruktion zu einem aufgeblähten,
schlecht lesbaren Code.
Ab der Java-Version 7 ist es
möglich, durch ein try-with-resources Statement
dies erheblich zu vereinfachen und das Schließen des
Stroms automatisch auszuführen.
Unter einer resource
wird hierbei ein Objekt verstanden, das nach Beendigung seiner
Aufgaben geschlossen werden muss. Hierzu gehören alle
Objekte, die das Interface java.lang.AutoClosable
implementieren.
Das obige Code-Beispiel kann hierzu auf die
u.a. Weise umgeformt werden. Das Einbetten des Codes in einen try-catch
-Block
ergibt sich hierbei aus der Notwendigkeit, dass die im
Hintergrund ausgeführte Methode close()
wie
oben bereits erläutert ihrerseites eine IOException
auslösen kann.
In den auf javabeginners.de
gezeigten Code-Beispielen wird nicht durchgängig, aber
weitgehend auf das automatische Schließen von Streams
verzichtet, um die Abwärtskompatibilität zu
gewährleisten.
int i; try (DataInputStream in = new DataInputStream(new FileInputStream("test.txt"))) { while ((i = in.read()) != -1) System.out.print(i); } catch (IOException e) { e.printStackTrace(); }
Die wesentlichen Stream-Klassen im Überblick
Die folgenden Auflistungen und schematischen Darstellungen von Zeichen- und Byte-orientierten Strömen und deren Klassenhierarchien sind nicht vollständig, sondern zeigen nur die gebräuchlisten Ströme.
Von Reader
abgeleitete Klassen:
Anwendungsbeispiele
- BufferedReader
- Programm starten
- HTML-Seite darstellen
- Von Tastatur lesen
- Von Tastatur in Datei schreiben
- InputStreamReader
- Programm starten
- HTML-Seite darstellen
- Von Tastatur lesen
- FileReader
- Eine Datei zeilenweise auslesen
- Eine Datei auslesen
- Json lesen
Von Writer
abgeleitete Klassen:
Anwendungsbeispiele
- BufferedWriter
- In Textdatei schreiben
- PrintWriter
- Browser starten
- ArrayList in Datei schreiben
- FileWriter
- Von Tastatur in Datei schreiben
- In Textdatei schreiben
- OutputStreamWriter
- XML-Datei lesen
Von InputStream
abgeleitete Klassen:
Anwendungsbeispiele
- InputStream
- Browser starten
- Programm starten
- HTML-Seite darstellen
- BufferedInputStream
- Primitive_Datentypen_speichern
- DataInputStream
- Primitive_Datentypen_speichern
- ObjectInputStream
- Daten serialisieren
- FileInputStream
- Byte-Array speichern und lesen
- Verzeichnisinhalt packen
- Eine Datei kopieren
- Primitive_Datentypen_speichern
Von OutputStream
abgeleitete Klassen:
Anwendungsbeispiele
- BufferedOutputStream
- Primitive_Datentypen_speichern
- ObjectOutputStream
- Daten serialisieren
- FileOutputStream
- Byte-Array speichern und lesen
- Eine Datei kopieren
- PDF schreiben
- Primitive_Datentypen_speichern
- XML-Datei schreiben
- PrintStream
- Socketverbindung
- ZipOutputStream
- Verzeichnisinhalt packen
Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.