Java BufferedReader Handbook

1. Quick Summary

BufferedReader reads text from a character-input stream, buffering characters so as to provide for the efficient reading of characters, arrays, and lines.

  • Package: java.io.BufferedReader

  • Key Feature: Reduces the number of I/O operations by reading large chunks of data into memory (buffer) at once.

  • Default Buffer Size: 8 KB (8192 chars).

2. Common Constructors

// 1. Wrapping a FileReader (Most Common)
BufferedReader br = new BufferedReader(new FileReader("file.txt"));
// 2. Reading from Console (System.in)
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 3. Custom Buffer
SizeBufferedReader br = new BufferedReader(new FileReader("file.txt"), 16384); // 16KB buffer

3. Essential Methods Cheat Sheet

Method

Return Type

Description

readLine()

String

Reads a line of text. Returns null if end of stream.

read()

int

Reads a single character (as an integer). Returns -1 if end.

skip(long n)

long

Skips n characters.

close()

void

Closes the stream and releases resources.

lines()

Stream<String>

(Java 8+) Returns a Stream of lines (lazy evaluation).


4. BufferedReader vs. Scanner

Feature

BufferedReader

Scanner

Speed

Faster (larger buffer, no parsing).

Slower (smaller buffer, parses regex).

Synchronized

Yes (Thread-safe).

No (Not thread-safe).

Parsing

Reads raw Strings only.

Can parse primitives (nextInt(), etc).

Exceptions

Throws checked IOException.

Hides exceptions (check ioException()).


5. Standard Implementation Pattern (Try-with-Resources)

Old Way (Pre-Java 7): messy finally blocks.Modern Way:

try (BufferedReader br = new BufferedReader(new FileReader("path/to/file.txt"))) {
    String line;
    while ((line = br.readLine()) != null) {
        // Process line
    }
} catch (IOException e) {
    e.printStackTrace();
}

6. Tips for Implementation

  1. Always use Try-with-Resources: This ensures the .close() method is called automatically, preventing memory leaks.

  2. Parsing: BufferedReader only reads Strings. If you need integers, you must parse manually: Integer.parseInt(br.readLine()).

  3. Fast I/O: For Competitive Programming, BufferedReader + StringTokenizer is the gold standard for speed.


Implementation examples

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.stream.Collectors;
/**
* A comprehensive demonstration of BufferedReader usages.
* * Includes:
* 1. Setup (creating a dummy file to read).
* 2. Classic while-loop reading.
* 3. Java 8 Stream API reading.
* 4. Reading input from Console.
*/
public class BufferedReaderExamples {
public static void main(String[] args) {
String filename = "demo_text.txt";

// SETUP: Create a dummy file for the demonstration
createDummyFile(filename);
System.out.println("=== 1. Classic Line-by-Line Reading ===");
readClassicStyle(filename);
System.out.println("\n=== 2. Java 8+ Stream API Reading ===");
readWithStreams(filename);

System.out.println("\n=== 3. Reading from String Source (Simulated Console) ===");
readFromString();

System.out.println("\n=== 4. Parsing Primitives (Manual Parsing) ===");
parsePrimitivesExample();
}
/**
* Pattern 1: The Classic "while loop" approach.
* Best for simple, sequential processing in older Java versions or
* when complex logic is required inside the loop.
*/
private static void readClassicStyle(String filename) {
// "try-with-resources" automatically closes the file
try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
String line;
// Common idiom: assign line inside the condition check
while ((line = br.readLine()) != null) {
System.out.println("Processing: " + line);
}
} catch (IOException e) {
System.err.println("Error reading file: " + e.getMessage());
}
}
/**
* Pattern 2: The Stream API approach (Java 8+).
* Best for filtering, mapping, and collecting data concisely.
*/
private static void readWithStreams(String filename) {
try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
// .lines() returns a Stream<String>
String result = br.lines()
.filter(line -> line.contains("Java")) // Filter logic
.map(String::toUpperCase) // Transformation logic
.collect(Collectors.joining(", ")); // Collection logic

System.out.println("Filtered & Joined Lines: " + result);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Pattern 3: Reading from a non-file source (like a String or Network stream).
* This uses StringReader, but the logic is identical to InputStreamReader(System.in).
*/
private static void readFromString() {
String inputData = "First Line\nSecond Line\nThird Line";

try (BufferedReader br = new BufferedReader(new StringReader(inputData))) {
System.out.println("First character code: " + br.read()); // Reads single char
System.out.println("Rest of first line: " + br.readLine());
br.skip(1); // Skip the 'S' of Second
System.out.println("Rest of stream: " + br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Pattern 4: How to handle numbers since BufferedReader only reads Strings.
*/
private static void parsePrimitivesExample() {
String numberData = "100\n200";
try (BufferedReader br = new BufferedReader(new StringReader(numberData))) {
int sum = 0;
String line;
while((line = br.readLine()) != null) {
// Must parse manually
sum += Integer.parseInt(line);
}
System.out.println("Sum of numbers: " + sum);
} catch (IOException | NumberFormatException e) {
e.printStackTrace();
}
}
// Helper method to generate a file for the demo
private static void createDummyFile(String filename) {
try (FileWriter writer = new FileWriter(filename)) {
writer.write("Hello World\n");
writer.write("Java BufferedReader is efficient\n");
writer.write("It buffers characters\n");
writer.write("End of file");
} catch (IOException e) {
System.err.println("Setup failed: " + e.getMessage());
}
}
}


← Back to Learning Journey