Java Notes
Complete guide to Buffered Streams in Java — BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter, performance benefits, line-by-line reading, and real-world file processing.
What are Buffered Streams?
Buffered streams add a memory buffer (internal array) between your program and the physical I/O device. Instead of making a system call for every byte/character, data is read or written in bulk chunks.
Without Buffer
Program ←→ [1 byte] ←→ Disk (thousands of slow system calls)
With Buffer
Program ←→ [8192 bytes buffer] ←→ Disk (few fast bulk reads)
Why Buffering Matters
Every disk read/write involves:
- System call overhead (user mode → kernel mode transition)
- Disk seek time (for HDDs)
- Transfer time
A single system call for 8KB costs almost the same as one for 1 byte. So reading 8192 bytes at once is ~8000× more efficient than reading 1 byte at a time.
The Four Buffered Stream Classes
| Class | Wraps | Purpose |
|---|---|---|
BufferedInputStream | InputStream | Buffered byte reading |
BufferedOutputStream | OutputStream | Buffered byte writing |
BufferedReader | Reader | Buffered character reading + readLine() |
BufferedWriter | Writer | Buffered character writing + newLine() |
BufferedReader — Line-by-Line Text Reading
The most commonly used buffered stream. Provides the essential readLine() method:
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output:
| 1 | Line 1: Java is a programming language |
| 2 | Line 2: It was created by James Gosling |
| 3 | Line 3: Released in 1995 |
| 4 | Line 4: Write once, run anywhere |
| 5 | Line 5: Over 3 billion devices run Java |
| First 20 chars | Line 1: Java is a pr |
| Read 50 chars | Line 1: Java is a programming language\nLine 2: It |
| After skipping 8 | Java is a programming language |
| Read line 2 | Line 2: It was created by James Gosling |
| Read line 2 again | Line 2: It was created by James Gosling |
| LINE 1 | JAVA IS A PROGRAMMING LANGUAGE |
| LINE 5 | OVER 3 BILLION DEVICES RUN JAVA |
BufferedWriter — Efficient Text Writing
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output:
BufferedInputStream & BufferedOutputStream
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Performance Comparison
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output (approximate):
| Test file | 5 MB |
| Unbuffered (byte-by-byte) | 4523 ms |
| BufferedInputStream | 38 ms |
| Manual 8KB buffer | 12 ms |
Custom Buffer Sizes
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Real-World Example: Log File Analyzer
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output:
| Total log entries | 14 |
| INFO | 8 entries |
| WARN | 2 entries |
| ERROR | 2 entries |
| DEBUG | 2 entries |
| 09 | 00 │ ████ (4) |
| 10 | 00 │ █████ (5) |
| 11 | 00 │ ███ (3) |
| 12 | 00 │ ██ (2) |
| ⚠ 10 | 30:45 [ERROR] Failed to connect to payment gateway |
| ⚠ 12 | 00:00 [ERROR] OutOfMemoryError in worker thread |
Reading from Console with BufferedReader
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Common Mistakes
1. Not understanding when to flush
// Data sits in buffer until buffer is full or stream is closed
BufferedWriter writer = new BufferedWriter(new FileWriter("file.txt"));
writer.write("Important data!");
// At this point, data might still be in the buffer, NOT on disk!
writer.flush(); // NOW it's on disk
// OR
writer.close(); // Also flushes before closing2. Wrapping already-buffered streams
// ❌ REDUNDANT: BufferedReader already has its own buffer
BufferedReader br = new BufferedReader(
new BufferedReader(new FileReader("file.txt"))); // Double buffering!
// ✅ CORRECT: One layer of buffering
BufferedReader br = new BufferedReader(new FileReader("file.txt"));3. Not checking readLine() for null
// ❌ BAD: NullPointerException when file ends
String line = reader.readLine();
line.trim(); // NPE if line is null!
// ✅ GOOD: Check for null
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
// process...
}Interview Questions
Q1: What is the default buffer size of BufferedReader?
Answer: 8192 characters (8KB for BufferedReader/BufferedWriter, 8192 bytes for BufferedInputStream/BufferedOutputStream). This can be customized via the constructor.
Q2: What is the difference between flush() and close()?
Answer: flush() writes buffered data to the underlying stream but keeps the stream open. close() calls flush() first, then releases the resource. After close(), you can't write anymore.
Q3: Why is BufferedReader faster than FileReader?
Answer: FileReader makes a system call for each read() invocation. BufferedReader reads a large chunk (8KB) from disk into memory in one system call, then serves subsequent read() requests from this memory buffer. Fewer system calls = much faster.
Q4: Does BufferedWriter's newLine() always write \n?
Answer: No! newLine() writes the platform-specific line separator: \r\n on Windows, \n on Linux/Mac. This ensures files are formatted correctly for the OS. Use it instead of hardcoding \n.
Q5: When should you call flush() explicitly?
Answer: When you need data to be written to the destination immediately without closing the stream. Common cases: (1) log entries that must persist immediately, (2) network communication where the receiver needs data NOW, (3) before reading from the same file in another stream.
Q6: Can BufferedReader read binary files?
Answer: No, BufferedReader is for text (characters). It expects valid character data and will corrupt binary data during encoding/decoding. Use BufferedInputStream for binary files.
Continue the lesson path