杰瑞科技汇

BufferedReader在Java中如何高效读取文件?

Of course! Let's dive deep into BufferedReader in Java. It's a fundamental class for efficient input, especially when reading text from a source like a file or the console.

BufferedReader在Java中如何高效读取文件?-图1
(图片来源网络,侵删)

What is BufferedReader?

BufferedReader is a Java class that reads text from an input stream (like a file or network connection) and buffers the characters to provide efficient reading of characters, arrays, and lines.

The key idea is "buffering". Instead of reading one character at a time from a slow source (like a disk), which is very inefficient, BufferedReader reads a large chunk of data (a "buffer") into memory at once. Then, it serves characters from this fast in-memory buffer, only going back to the slow source when the buffer is empty. This dramatically improves performance.

The Core Concept: Buffering

Think of it like pouring a drink from a large soda bottle into a small glass.

  • Without Buffering: Every time you want a sip, you have to take the cap off the bottle, pour a tiny bit, and put the cap back on. This is slow and tedious.
  • With Buffering: You pour a whole glass of soda from the bottle. Now, you can take many sips quickly without touching the bottle. The glass is your "buffer."

BufferedReader does the same thing for I/O.

BufferedReader在Java中如何高效读取文件?-图2
(图片来源网络,侵删)

How to Use BufferedReader

You'll typically use BufferedReader in a two-step process:

  1. Wrap a lower-level Reader: You don't create a BufferedReader directly on a file. You first create a FileReader (which connects to the file) and then wrap that FileReader inside the BufferedReader.
  2. Use its methods: Now you can use the efficient methods of BufferedReader like readLine().

Basic Example: Reading from a File

This is the most common use case.

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class BufferedReaderExample {
    public static void main(String[] args) {
        // The path to the file you want to read
        String filePath = "my_document.txt";
        // The try-with-resources statement ensures that the reader is closed automatically.
        // This is the best practice and prevents resource leaks.
        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
            String line; // This will hold each line as we read it
            // The readLine() method reads a line of text.
            // It returns null when the end of the stream (the file) is reached.
            while ((line = reader.readLine()) != null) {
                // Print the line to the console
                System.out.println(line);
            }
        } catch (IOException e) {
            // Handle potential exceptions (e.g., file not found)
            System.err.println("An error occurred while reading the file: " + e.getMessage());
        }
    }
}

Explanation:

  • new FileReader(filePath): Creates a FileReader that is connected to the file my_document.txt. This is the low-level, potentially slow stream.
  • new BufferedReader(...): Wraps the FileReader. Now, any operation on the BufferedReader will be buffered and efficient.
  • try-with-resources (try (BufferedReader reader = ...)): This is a modern Java feature. It automatically closes thereaderwhen thetry` block is finished, even if an error occurs. This is crucial for resource management.
  • reader.readLine(): This is the star method of BufferedReader. It reads an entire line of text (up to the next newline character \n) and returns it as a String. It's much more convenient than reading character by character.
  • while ((line = reader.readLine()) != null): This is a standard Java idiom. It reads a line, assigns it to the line variable, and then checks if the result is null (which signals the end of the file). The loop continues as long as we are getting lines.

Key Methods of BufferedReader

Method Description
readLine() Most Important. Reads a line of text. A line is considered to be terminated by a line feed (\n), a carriage return (\r), or a carriage return followed immediately by a line feed (\r\n). Returns null when the end of the stream is reached.
read() Reads a single character. Returns the character as an integer, or -1 if the end of the stream has been reached.
read(char[] cbuf, int off, int len) Reads characters into a portion of an array. This is more efficient than calling read() in a loop.
close() Closes the stream and releases any system resources associated with it. Automatically handled by try-with-resources.
ready() Tells whether this stream is ready to be read. A return of true guarantees that read() will not block, but a false does not guarantee that the stream will not block on the next read.

BufferedReader vs. Scanner

Both BufferedReader and Scanner are used for reading input, but they have different strengths and are used in different contexts.

Feature BufferedReader Scanner
Primary Use Case Reading text files efficiently. Parsing primitive types and strings from various sources (console, files, etc.).
Speed Generally faster for reading raw text because of its large default buffer size (8KB). Slower due to its smaller internal buffer and the overhead of parsing tokens.
Tokenization No built-in tokenization. It reads lines or characters. It does not understand "tokens" like numbers or words. Built-in tokenization. It can easily parse int, double, String, etc., using methods like nextInt(), nextDouble().
Source Requires wrapping another Reader (e.g., FileReader, InputStreamReader). Can directly take a File or an InputStream in its constructor, making it simpler for console input (System.in).
Line Separator readLine() uses the system's default line separator. nextLine() uses the system's default line separator.

When to Use Which?

  • Use BufferedReader when:

    • You are reading large text files and performance is critical.
    • You only need to read lines or characters.
    • You are working in an environment where minimizing dependencies is important (e.g., competitive programming).
  • Use Scanner when:

    • You need to read formatted input (e.g., a file with numbers and text mixed together).
    • You are reading from the console (System.in) and want a simple way to get numbers or words.
    • You need to use methods like hasNextInt() or nextInt().

Example: Scanner for Console Input

import java.util.Scanner;
public class ScannerExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Enter your name: ");
        String name = scanner.nextLine(); // Reads a full line
        System.out.print("Enter your age: ");
        int age = scanner.nextInt(); // Reads an integer
        System.out.println("Hello, " + name + "! You are " + age + " years old.");
        scanner.close(); // Important to close the scanner
    }
}

Best Practices

  1. Always use try-with-resources: This is the most important practice. It prevents resource leaks and makes your code cleaner and safer.
  2. Choose the right tool: For raw text file reading, BufferedReader is the king of performance. For parsing user input or mixed data, Scanner is often more convenient.
  3. Handle IOException: File I/O can fail for many reasons (file not found, permission denied, disk full). Always handle IOException.
分享:
扫描分享到社交APP
上一篇
下一篇