Wie arbeitet man mit Datenströmen?

Datenströme sind kontinuierliche Abfolgen von Daten eines Typs, die in Java in die beiden Gruppen der Byte-orientierten und der Zeichen-orientierten Ströme untergliedert werden.

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 beispielhaft an einem DataInputStream erläutert. Er liest primitive Daten von einem zugrunde liegenden InputStream, hier aus einer Datei.

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 im 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 die Methode close() ihrerseits eine IOException auslösen kann, muss auch hier wiederum ein try-catch-Block eingesetzt werden.

try-with-resources Statement

7.0Wie deutlich erkennbar, so führen diese Notwendigkeiten 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() ihrerseites eine IOException auslösen kann.

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

In den auf javabeginners.de gezeigten Code-Beispielen wird weitgehend auf das automatische Schließen von Streams verzichtet, um die Abwärtskompatibilität zu gewährleisten.

Von Reader abgeleitete Klassen:

Ihr Browser unterstützt das HTML5-Canvaselement nicht.

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:

Ihr Browser unterstützt das HTML5-Canvaselement nicht.

Anwendungsbeispiele

BufferedWriter
In Textdatei schreiben
PrintWriter
Browser starten
ArrayList in Datei schreiben
FileWriter
Von Tastatur in Datei schreiben
In Textdatei schreiben

Von InputStream abgeleitete Klassen:

Ihr Browser unterstützt das HTML5-Canvaselement nicht.

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:

Ihr Browser unterstützt das HTML5-Canvaselement nicht.

Anwendungsbeispiele

BufferedOutputStream
Primitive_Datentypen_speichern
ObjectOutputStream
Daten serialisieren
FileOutputStream
Byte-Array speichern und lesen
Eine Datei kopieren
PDF schreiben
Primitive_Datentypen_speichern
ZipOutputStream
Verzeichnisinhalt packen