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?
IntermediateAnswer
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 fasterReal-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.