BufferedWriter is a character-stream class used to write text to a character-output stream, buffering characters so as to provide for the efficient writing of single characters, arrays, and strings. By reducing the frequency of native write calls to the operating system, it can drastically improve the performance of your I/O operations.
In a standard FileWriter, every call to write() triggers a physical action on the storage device. Disk drives (especially HDDs) are thousands of times slower than the CPU. If you write 10,000 characters individually, your program will spend 99% of its time waiting for the disk to finish.
Imagine you are moving water from a tank to a garden. FileWriter is like moving water with a tiny spoon. BufferedWriter is like filling a large bucket first, then carrying the whole bucket to the garden in one trip. The "Bucket" in Java is an internal array (usually 8,192 characters/8KB) stored in the RAM.
Like its cousin BufferedReader, BufferedWriter uses the Decorator Pattern. It is not a standalone writer that talks to a file; it is a "wrapper" that enhances an existing Writer.
Writer fw = new FileWriter("output.txt"); // The base layerBufferedWriter bw = new BufferedWriter(fw); // The enhanced layer
BufferedWriter inherits methods from Writer but adds some essential functionality for formatting and performance:
| Method | Why it matters |
|---|---|
void write(String s) |
Writes a string directly into the buffer. Very convenient for text processing. |
void newLine() |
Writes a line separator. Crucial: This uses the system's own line separator (Windows uses \r\n, Unix uses \n), making your code cross-platform. |
void flush() |
Forces the buffer to empty its content to the disk immediately. Essential if you want the user to see data before the stream is closed. |
void close() |
Flushes the stream first and then closes it. Once closed, no more writing is possible. |
This is the #1 mistake junior developers make. Because BufferedWriter stores data in RAM, if your program finishes or crashes before the close() or flush() method is called, the data currently sitting in the "bucket" will never reach the file. Your file will appear empty or cut off.
close() (and thus flush()) even if an exception occurs during the writing process.
This example demonstrates how to export a list of items to a text file efficiently while maintaining cross-platform compatibility using newLine().
If you are writing on a very high-latency network drive, the default 8KB buffer might still be too small. You can pass a second parameter to the constructor to define your own buffer size.
// Setting a 64KB buffer for massive data throughputBufferedWriter bw = new BufferedWriter(new FileWriter("bigdata.txt"), 65536);
Many developers use PrintWriter because it has the println() method (just like System.out). While PrintWriter is more convenient, BufferedWriter is strictly faster for high-volume writing because its buffering logic is simpler and lacks the overhead of auto-flushing and formatting found in PrintWriter.
Q: What is the main advantage of BufferedWriter over FileWriter?
A: Performance. It reduces the number of expensive system calls to the OS by grouping small write requests into a large buffer in memory.
Q: Why should you use newLine() instead of \n?
A: \n is the newline character for Linux/Unix. Windows uses \r\n. Using newLine() ensures your file looks correct on all operating systems.
Q: Can BufferedWriter be used with FileOutputStream?
A: Not directly. BufferedWriter takes a Writer. To bridge them, you must use OutputStreamWriter like this:
new BufferedWriter(new OutputStreamWriter(new FileOutputStream("file.txt"))).
The BufferedWriter is not just a tool; it's a performance optimization strategy. In any professional Java application, direct file writing is almost never seen. By mastering the buffer, understanding the importance of the flush() and close() cycle, and using the newLine() method, you ensure your applications are fast, stable, and cross-platform compatible.