EMZETT.
Login

BufferedWriter

Kurz: Ein Character-Stream, der Schreibzugriffe puffert, bevor sie tatsächlich auf die Festplatte geschrieben werden — wrappt meist einen FileWriter.

Genauer: Gepufferte Daten landen erst beim Schließen (oder explizitem flush()) sicher auf der Festplatte — wird der Writer nicht ordnungsgemäß geschlossen (z. B. bei einem Absturz), können gepufferte, noch nicht geschriebene Daten verloren gehen. try-with-resources verhindert genau dieses Problem zuverlässig.

Im Detail

try (BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"))) {
    for (int i = 1; i <= 5; i++) {
        bw.write("Zeile " + i);
        bw.newLine(); // plattformunabhängiger Zeilenumbruch, besser als "\n" hartkodiert
    }
} catch (IOException e) {
    System.err.println("Fehler beim Schreiben: " + e.getMessage());
}

bw.newLine() schreibt den Zeilenumbruch, der zum aktuellen Betriebssystem passt (\n unter Linux/macOS, \r\n unter Windows) — portabler als ein hartkodiertes "\n". Wer new FileWriter("output.txt", true) (zweites Argument true = Append-Modus) nutzt, hängt neue Zeilen ans Ende einer bestehenden Datei an, statt sie zu überschreiben. Ein manuelles bw.flush() erzwingt, dass gepufferte Daten sofort auf die Festplatte geschrieben werden, auch bevor der Writer geschlossen wird — nützlich bei langlaufenden Prozessen, bei denen man den aktuellen Fortschritt nicht erst beim Programmende sichern will.

Warum Pufferung beim Schreiben genauso wichtig ist

Jeder einzelne write()-Aufruf auf einen ungepufferten FileWriter kann einen eigenen, teuren Systemaufruf zum Betriebssystem auslösen. BufferedWriter sammelt Schreibzugriffe stattdessen im Speicher und schreibt sie erst als größeren Block auf einmal auf die Festplatte, sobald der interne Puffer voll ist, flush() aufgerufen wird oder der Writer geschlossen wird. Bei vielen kleinen Schreibzugriffen (z. B. Zeile für Zeile in einer Schleife) macht das einen erheblichen Geschwindigkeitsunterschied.

Das Risiko unvollständiger Daten

Genau diese Pufferung hat eine Kehrseite: Solange der Puffer nicht geleert wurde, existieren die “geschriebenen” Daten nur im Arbeitsspeicher des Programms, nicht auf der Festplatte. Stürzt das Programm ab oder wird der Prozess hart beendet, bevor close()/flush() aufgerufen wurde, gehen diese gepufferten Daten verloren — die Datei enthält dann nur den Teil, der schon tatsächlich geschrieben wurde. try-with-resources garantiert, dass close() (und damit ein finaler flush()) auch bei einer Exception innerhalb des Blocks zuverlässig aufgerufen wird:

try (BufferedWriter bw = new BufferedWriter(new FileWriter("kritisch.log"))) {
    bw.write("Wichtiger Log-Eintrag");
    bw.newLine();
    verarbeiteWeiter(); // wirft evtl. eine Exception
    // egal was passiert: bw.close() (inkl. flush) läuft trotzdem garantiert
} catch (IOException e) {
    System.err.println("Fehler beim Schreiben: " + e.getMessage());
}

Zeichenkodierung nicht vergessen

new FileWriter("datei.txt") nutzt ohne weitere Angabe die Standard-Zeichenkodierung des Betriebssystems, was zwischen verschiedenen Systemen (Windows vs. Linux) zu inkonsistenten Umlauten führen kann. Sauberer ist die explizite Angabe: new FileWriter("datei.txt", StandardCharsets.UTF_8), um plattformunabhängig immer dieselbe Kodierung zu garantieren.

Siehe auch: BufferedReader, Write Files, try-with-resources