Eingabe-Ausgabe-Ströme (I/O Streams) sind eines der grundlegenden Konzepte in Java, das schon in frühen Versionen der Sprache eingeführt wurde. Dieses Konzept wurde ursprünglich entwickelt, um die Prozesse des Lesens und Schreibens von Daten zu abstrahieren: Ein Stream kann mit einer Datei, einem Netzwerk oder sogar der Konsole verbunden sein – für den Code sieht das identisch aus.
Ein Problem tritt auf, wenn der Entwickler die Streams nicht richtig verwaltet, sie vergisst zu schließen oder verschiedene Stream-Typen (Zeichen- und Byte-Streams) verwechselt, was häufig zu Ressourcenlecks, Datenverfälschungen oder Laufzeitfehlern führt.
Die Lösung ist ein fundiertes Verständnis und die Anwendung der Hierarchie der Eingabe-Ausgabe-Ströme (InputStream/OutputStream für Bytes, Reader/Writer für Zeichen) sowie das zwingende Schließen der Streams nach der Benutzung, vorzugsweise durch try-with-resources seit Java 7.
Beispielcode für das Lesen und Schreiben einer Datei:
try (BufferedReader reader = new BufferedReader(new FileReader("input.txt")); BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) { String line; while ((line = reader.readLine()) != null) { writer.write(line); writer.newLine(); } }
Wichtige Merkmale:
Was passiert, wenn man einen Eingabe-Ausgabe-Stream in Java nicht schließt?
Streams verwenden niedrigstufige Betriebssystemressourcen, und das Nichtschließen eines Streams kann zu Speicherlecks, Dateisperrungen, Anwendungsfehlern oder sogar zu einem Erschöpfen der Datei-Deskriptoren auf Betriebssystemebene führen.
Kann man denselben OutputStream zum Schreiben in verschiedene Dateien verwenden?
Nein, der klassische OutputStream ist fest mit einer Quelle/ einem Ziel verbunden. Für verschiedene Dateien sind verschiedene OutputStream-Objekte erforderlich.
Was ist der Unterschied zwischen PrintWriter und BufferedWriter? Wann sollte man welchen verwenden?
PrintWriter spezialisiert sich auf die Erweiterung der Ausgabe mit formatierten Druckmethoden, z. B. println(), und unterstützt das automatische Spülen. BufferedWriter hingegen erhöht vor allem die Leistung durch Pufferung. In den meisten Anwendungsfällen ist PrintWriter für die textuelle Ausgabe vorzuziehen, aber wenn einfach nur schnell Zeichen oder Strings ohne Formatierung geschrieben werden müssen, ist BufferedWriter besser geeignet.
Ein Entwickler liest Daten aus einer großen Datei mit FileInputStream, nutzt keine Pufferung und vergisst, den Stream zu schließen.
Vorteile:
Nachteile:
Es wird die Kombination BufferedReader mit try-with-resources verwendet, das Lesen und Verarbeiten erfolgt in Paketen pro Zeile, der Stream wird automatisch geschlossen.
Vorteile:
Nachteile: