All 15 I/O & NIO questions
More in I/O & NIO
Advertisement
Java › I/O & NIO

How does wrapping a FileInputStream in a BufferedInputStream (or FileReader in a BufferedReader) improve I/O performance, and what's the mechanism behind this improvement?

Intermediate

Answer

Unbuffered I/O typically issues a separate, relatively expensive system call to the underlying OS for every single read/write operation (even reading just one byte), while a buffered wrapper reads (or writes) data in larger chunks into an internal in-memory buffer, satisfying many subsequent small read/write calls directly from that buffer without touching the OS again until the buffer is exhausted or needs refilling -- this dramatically reduces the number of actual system calls for typical usage patterns involving many small reads/writes, a substantial and easily-obtained performance improvement essentially free to apply by simply wrapping the unbuffered stream.
// Unbuffered: potentially one system call PER character read
Reader unbuffered = new FileReader("large.txt");
int c;
while ((c = unbuffered.read()) != -1) { /* process character */ }  // slow for large files

// Buffered: reads in large chunks internally, dramatically fewer system calls
BufferedReader buffered = new BufferedReader(new FileReader("large.txt"));
String line;
while ((line = buffered.readLine()) != null) { /* process line */ }  // much faster
Real-world example A log file parser processing a multi-gigabyte file sees a dramatic performance improvement simply by wrapping its FileReader in a BufferedReader, reducing what would have been millions of individual system calls (one per character or small read) down to a much smaller number of larger, buffered reads.

Common follow-ups: What's a reasonable default buffer size, and does it matter much for typical use cases?;Does BufferedReader's readLine() handle different line-ending conventions (\n vs \r\n) correctly across platforms?