Reading disk files byte-by-byte or character-by-character is notoriously slow because every single read triggers a physical disk sector read or OS kernel context switch. Buffered Streams solve this bottleneck by wrapping existing streams with an internal memory buffer (default 8 KB), drastically reducing OS-level system calls.
BufferedReader provides the invaluable readLine() method, which reads an entire line of text up to a newline character (\n, \r, or \r\n) and returns it as a String, or null when the end of file is reached.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class FastFileRead {
public static void main(String[] args) {
String filePath = "server-logs.txt";
try (BufferedReader reader = new BufferedReader(new FileReader(filePath, StandardCharsets.UTF_8))) {
String line;
int lineNumber = 1;
while ((line = reader.readLine()) != null) {
System.out.printf("[%04d] %s%n", lineNumber++, line);
}
} catch (IOException e) {
System.err.println("Read error: " + e.getMessage());
}
}
}
BufferedWriter caches outgoing characters in an 8 KB buffer and flushes them to disk when full. PrintWriter wraps writers to provide familiar methods like println() and printf().
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class FastFileWrite {
public static void main(String[] args) {
try (FileWriter fw = new FileWriter("students.csv", StandardCharsets.UTF_8, false);
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter out = new PrintWriter(bw)) {
out.println("RollNo,Name,Course,Grade");
out.printf("%d,%s,%s,%.1f%n", 101, "Aarav Sharma", "BCA", 92.5);
out.printf("%d,%s,%s,%.1f%n", 102, "Neha Patel", "MCA", 88.0);
out.printf("%d,%s,%s,%.1f%n", 103, "Rohan Verma", "B.Tech", 95.2);
System.out.println("CSV export completed successfully.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
| Feature | BufferedReader | Scanner |
|---|---|---|
| Purpose | Raw, high-speed character stream reading | Parsing primitives & tokens using Regex |
| Buffer Size | 8,192 characters (8 KB) | 1,024 characters (1 KB) |
| Synchronization | Synchronized (Thread-Safe) | Not Synchronized (Not Thread-Safe) |
| Execution Speed | Extremely Fast (~10x faster) | Slower due to Regex tokenization overhead |
| Exception Handling | Requires throws IOException or try-catch | Hides IOException (checks ioException()) |
| Best Used For | Large files, competitive programming, bulk logs | Interactive CLI user input parsing (integers, strings) |
| Iteration | reader.readLine() Result | line Variable | Loop Condition | Action Taken |
|---|---|---|---|---|
| 1 | "101,Aarav Sharma,BCA,92.5" | Points to String on Heap | != null (TRUE) | Prints formatted line 1 |
| 2 | "102,Neha Patel,MCA,88.0" | Points to String on Heap | != null (TRUE) | Prints formatted line 2 |
| 3 | "103,Rohan Verma,B.Tech,95.2" | Points to String on Heap | != null (TRUE) | Prints formatted line 3 |
| 4 | null (EOF) | null | != null (FALSE) | Loop exits; try-with-resources closes buffer & stream |
Scanner in competitive programming when input exceeds 100,000 lines?
Scanner uses regular expressions internally for every nextInt() or next() call and has a small 1 KB buffer. On large datasets, this causes severe Time Limit Exceeded (TLE) errors. BufferedReader coupled with StringTokenizer is the standard fast I/O pattern.bw.newLine() writes a platform-independent newline separator (\r\n on Windows, \n on UNIX).Accelerate your Java mastery by studying these tightly connected core tutorials:
Core Byte and Character stream fundamentals.
Modern Files.readAllLines() and Files.lines().
Automatic stream flushing and closing.
String splitting and token processing.