Buffered Streams
Buffered Streams in Java improve I/O performance by reducing the number of direct interactions with the underlying file system or device. They wrap existing streams and use an in-memory buffer to read/write data in larger chunks instead of byte-by-byte or char-by-char.
This is a must-know Core Java I/O topic and a common interview question.
What Are Buffered Streams?
- Streams that use an internal buffer
- Reduce disk I/O operations
- Increase performance significantly
- Part of the java.io package
- Available for both byte and character streams
Why Buffered Streams Are Needed
Without Buffering
- Frequent disk access
- Slow performance
- High I/O overhead
With Buffering
- Fewer disk reads/writes
- Faster execution
- Efficient memory usage
Types of Buffered Streams
- 1️⃣ Buffered Byte Streams
- BufferedInputStream
- BufferedOutputStream
- 2️⃣ Buffered Character Streams
- BufferedReader
- BufferedWriter
Buffered Byte Streams
BufferedInputStream
Used to read binary data efficiently.
BufferedInputStream bis =
new BufferedInputStream(new FileInputStream("image.jpg"));
int data;
while ((data = bis.read()) != -1) {
// process byte
}
bis.close();
- ✔ Uses byte buffer
- ✔ Faster than FileInputStream
BufferedOutputStream
Used to write binary data efficiently.
BufferedOutputStream bos =
new BufferedOutputStream(new FileOutputStream("copy.jpg"));
bos.write(65);
bos.flush();
bos.close();
- ✔ Data written in chunks
- ✔ flush() forces buffer write
Buffered Character Streams
BufferedReader (Most Common)
Used to read text efficiently, supports line-by-line reading.
BufferedReader br =
new BufferedReader(new FileReader("data.txt"));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
- ✔ Very fast
- ✔ Supports readLine()
BufferedWriter
Used to write text efficiently.
BufferedWriter bw =
new BufferedWriter(new FileWriter("out.txt"));
bw.write("Hello Java");
bw.newLine();
bw.close();
- ✔ Efficient
- ✔ Platform-independent line separator
Buffered Streams Class Hierarchy
Byte Streams
InputStream
└── FilterInputStream
└── BufferedInputStream
OutputStream
└── FilterOutputStream
└── BufferedOutputStream
Character Streams
Reader
└── BufferedReader
Writer
└── BufferedWriter
How Buffering Works Internally
- Reads/writes blocks of data into memory
- Serves data from buffer instead of disk
- Disk accessed only when buffer is empty/full
Disk ↔ Buffer ↔ Program
Buffer Size
Default buffer size:
- 8 KB (8192 bytes/chars)
Custom buffer size:
new BufferedInputStream(new FileInputStream("a.bin"), 16384);
- ✔ Larger buffers → fewer I/O calls
- ⚠ Too large → memory waste
Buffered Streams vs Unbuffered Streams (Interview Table)
| Aspect | Buffered | Unbuffered |
|---|---|---|
| Performance | Fast | Slow |
| Memory | Uses buffer | Minimal |
| Disk I/O | Less | More |
| Recommended | ✔ Yes | ❌ No |
Buffered Streams vs Byte/Character Streams
- Buffered streams are wrappers, not standalone
- Work on top of existing streams
- Improve performance only
Common Beginner Mistakes
- Not using buffering for large files
- Forgetting flush() before close (output)
- Mixing byte and character streams incorrectly
- Using buffered streams for very small data unnecessarily
Best Practices (Production-Grade)
- Always use buffered streams for file I/O
- Use BufferedReader for text files
- Use BufferedInputStream for binary files
- Combine with try-with-resources
try (BufferedReader br =
new BufferedReader(new FileReader("a.txt"))) {
// read logic
}
Buffered Streams vs NIO (Modern Java)
- Buffered Streams → classic I/O
- NIO (Files, Channels) → faster, scalable
- Interviews expect buffered streams knowledge
Interview-Ready Answers
Short Answer
Buffered streams improve I/O performance by reducing disk access.
Detailed Answer
In Java, buffered streams wrap existing input or output streams and use an internal buffer to read or write data in chunks. This significantly improves performance by minimizing direct disk I/O operations and is applicable to both byte and character streams.
Key Takeaway
Buffered Streams = Performance Optimization for I/O. Always buffer file operations to achieve faster and more efficient input/output.
Buffered Stream Examples and Interview Notes
1. Writing Data Using BufferedOutputStream
import java.io.*;
class Demo {
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("buffer.bin");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.write(65); // 'A'
bos.write(66); // 'B'
bos.close();
}
}
Key Point: Data is written first to a memory buffer, then to disk.
2. Reading Data Using BufferedInputStream
import java.io.*;
class Demo {
public static void main(String[] args) throws Exception {
BufferedInputStream bis =
new BufferedInputStream(new FileInputStream("buffer.bin"));
int b;
while ((b = bis.read()) != -1) {
System.out.print((char) b);
}
bis.close();
}
}
3. Copying File Using Buffered Byte Streams (Recommended)
import java.io.*;
class Demo {
public static void main(String[] args) throws Exception {
BufferedInputStream bis =
new BufferedInputStream(new FileInputStream("source.bin"));
BufferedOutputStream bos =
new BufferedOutputStream(new FileOutputStream("target.bin"));
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = bis.read(buffer)) != -1) {
bos.write(buffer, 0, bytesRead);
}
bis.close();
bos.close();
}
}
- Interview Favorite: Efficient file copy
- Reduced disk I/O
4. Writing Text Using BufferedWriter
import java.io.*;
class Demo {
public static void main(String[] args) throws Exception {
BufferedWriter bw =
new BufferedWriter(new FileWriter("text.txt"));
bw.write("Java");
bw.newLine();
bw.write("Buffered Writer");
bw.close();
}
}
5. Reading Text Line-by-Line Using BufferedReader
import java.io.*;
class Demo {
public static void main(String[] args) throws Exception {
BufferedReader br =
new BufferedReader(new FileReader("text.txt"));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
}
}
6. Copying Text File Using Buffered Character Streams
import java.io.*;
class Demo {
public static void main(String[] args) throws Exception {
BufferedReader br =
new BufferedReader(new FileReader("source.txt"));
BufferedWriter bw =
new BufferedWriter(new FileWriter("target.txt"));
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
}
br.close();
bw.close();
}
}
7. Appending Data Using BufferedWriter
import java.io.*;
class Demo {
public static void main(String[] args) throws Exception {
BufferedWriter bw =
new BufferedWriter(new FileWriter("log.txt", true));
bw.write("New log entry");
bw.newLine();
bw.close();
}
}
8. Why Buffering Improves Performance (Concept)
- FileOutputStream → disk write per byte ❌
- BufferedOutputStream → disk write per block ✅
9. flush() vs close()
BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));
bw.write("Data");
bw.flush(); // forces write, stream still open
// bw.close(); // flush + close
Interview Tip: close() internally calls flush().
10. Forgetting to Close Buffered Streams (Trap)
BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));
bw.write("Hello");
// ❌ data may not be written without close/flush
11. Try-With-Resources (Best Practice)
import java.io.*;
class Demo {
public static void main(String[] args) throws Exception {
try (BufferedReader br =
new BufferedReader(new FileReader("text.txt"))) {
System.out.println(br.readLine());
}
}
}
12. Combining Buffered Streams with Encoding
import java.io.*;
import java.nio.charset.StandardCharsets;
class Demo {
public static void main(String[] args) throws Exception {
BufferedReader br =
new BufferedReader(
new InputStreamReader(
new FileInputStream("utf8.txt"),
StandardCharsets.UTF_8));
System.out.println(br.readLine());
br.close();
}
}
13. Default Buffer Size (Interview Question)
BufferedInputStream bis = new BufferedInputStream(fis);
Explanation: Default buffer ≈ 8 KB. Can customize size if needed.
14. Custom Buffer Size
BufferedInputStream bis =
new BufferedInputStream(new FileInputStream("a.bin"), 16384);
15. Buffered Streams with Large Files
- Always prefer Buffered streams
- Especially for logs, reports, downloads
16. Buffered vs Unbuffered (Code Comparison)
FileInputStream fis = new FileInputStream("a.txt"); // slow
BufferedInputStream bis = new BufferedInputStream(fis); // fast
17. BufferedReader vs Scanner (Interview)
BufferedReader → faster, low-level
Scanner → slower, parsing support
18. Reading Only First Line
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
System.out.println(br.readLine());
br.close();
19. Real-World Use Cases
- Reading logs
- Writing reports
- Test automation output files
- Configuration files
20. Interview Summary – Buffered Streams
- BufferedInputStream
- BufferedOutputStream
- BufferedReader
- BufferedWriter
Key Points: Wraps low-level streams, improves performance, reduces disk I/O, must close or flush, preferred for large data.