BufferedWriter (Gepufferte Ausgabe)
Kurz: Ein Wrapper um einen Ausgabe-Stream, der zu schreibende Daten erst im Speicher sammelt und sie gebündelt in größeren Blöcken schreibt, statt bei jedem einzelnen Aufruf sofort physisch zu schreiben.
Genauer: Das spart teure einzelne Schreibzugriffe auf Festplatte oder Netzwerk und beschleunigt vor allem viele kleine, aufeinanderfolgende Schreiboperationen erheblich. Wichtig: Ein Puffer wird nicht automatisch sofort geleert — ohne abschließendes “Flush” bzw. Schließen des Streams können gepufferte, aber noch nicht geschriebene Daten verloren gehen.
Im Detail
Der Geschwindigkeitsunterschied zwischen gepuffertem und ungepuffertem Schreiben ist bei vielen kleinen Operationen dramatisch:
// UNGEPUFFERT: jeder einzelne write()-Aufruf kann einen teuren Systemaufruf auslösen
FileWriter roh = new FileWriter("datei.txt");
for (String zeile : zehntausendZeilen) {
roh.write(zeile); // potenziell 10.000 einzelne, langsame Schreibzugriffe
}
// GEPUFFERT: Daten sammeln sich im Speicher, physisches Schreiben in wenigen großen Blöcken
BufferedWriter gepuffert = new BufferedWriter(new FileWriter("datei.txt"));
for (String zeile : zehntausendZeilen) {
gepuffert.write(zeile); // landet zunächst nur im Puffer
}
gepuffert.close(); // hier werden restliche gepufferte Daten tatsächlich geschriebenDer Puffer ist im Grunde ein Zwischenspeicher (ein internes Array) im Arbeitsspeicher: Statt jeden geschriebenen Wert sofort an das Betriebssystem weiterzureichen (das dann selbst entscheidet, wann tatsächlich physisch auf den Datenträger geschrieben wird — ebenfalls oft gepuffert), sammelt der BufferedWriter erst eine größere Menge und übergibt sie dann in einem einzigen, effizienteren Aufruf.
Die wichtigste Konsequenz aus diesem Design: Ein write()-Aufruf garantiert NICHT, dass die Daten bereits physisch gespeichert sind — sie können sich noch ausschließlich im Puffer befinden. Stürzt das Programm ab, bevor der Puffer geleert wurde, gehen diese Daten verloren, obwohl der Code scheinbar erfolgreich geschrieben hat. Es gibt zwei Wege, den Puffer zu leeren:
flush()— leert den Puffer explizit, ohne den Stream zu schließen (nützlich, wenn weiterhin geschrieben werden soll, aber der bisherige Stand bereits gesichert sein muss).close()— leert den Puffer UND schließt den Stream (die übliche, empfohlene Variante am Ende der Nutzung, idealerweise über try-with-resources garantiert).
Siehe auch: I/O Streams, BufferedReader, Write Files