緩衝流是 Java IO 體系中提升讀寫效率的關鍵裝飾者。本文聚焦字符緩衝流 BufferedReader 與 BufferedWriter,涵蓋類繼承體系、核心構造方法、關鍵 API、實戰複製文本文件、裝飾模式設計思想,助你掌握高效文本處理技巧。
Reader (抽象基類)
├── BufferedReader
├── InputStreamReader (位元組轉字符橋梁)
│ └── FileReader (便捷類,預設編碼)
├── StringReader
...
Writer (抽象基類)
├── BufferedWriter
├── OutputStreamWriter (字符轉位元組橋梁)
│ └── FileWriter (便捷類,預設編碼)
├── StringWriter
...
BufferedReader(Reader in):預設緩衝區 8192 字符(8KB)。BufferedReader(Reader in, int sz):自訂緩衝區大小。| 方法 | 說明 |
|---|---|
int read() | 讀取單字符,返回 int(字符值),末尾返回 -1 |
int read(char[] cbuf, int off, int len) | 批量讀入字符陣列,返回實際讀取字符數 |
String readLine() | 核心優勢:按行讀取(遇 \n、\r 或 \r\n 終止),不包含換行符,末尾返回 null |
boolean ready() | 判斷流是否就緒可讀 |
void close() | 關閉流並釋放資源(會關閉底層 Reader) |
void mark(int readAheadLimit) / reset() | 標記/重置位置(支援回溯) |
BufferedWriter(Writer out):預設緩衝區 8192 字符。BufferedWriter(Writer out, int sz):自訂緩衝區大小。| 方法 | 說明 |
|---|---|
void write(int c) | 寫入單字符 |
void write(char[] cbuf, int off, int len) | 寫入字符陣列片段 |
void write(String s, int off, int len) | 寫入字符串片段 |
void newLine() | 跨平台換行:依系統屬性 line.separator 寫入 \n (Linux/Mac) 或 \r\n (Windows) |
void flush() | 強制刷新緩衝區至底層流 |
void close() | 刷新並關閉流(關閉底層 Writer) |
import java.io.*;
public class BufferedCopyDemo {
public static void main(String[] args) {
File src = new File("F:/source.txt");
File dest = new File("F:/target.txt");
copyFile(src, dest);
}
private static void copyFile(File src, File dest) {
try (Reader reader = new FileReader(src);
BufferedReader br = new BufferedReader(reader);
Writer writer = new FileWriter(dest);
BufferedWriter bw = new BufferedWriter(writer)) {
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine(); // 跨平台換行,必須配合 readLine() 使用
}
bw.flush(); // 確保最後緩衝數據落盤
} catch (IOException e) {
e.printStackTrace();
}
}
}
readLine() 丟棄換行符,寫入時必須手動 newLine() 補回,否則輸出會合併成單行。flush() 或 close() 觸發。FileReader/FileWriter 使用平台預設編碼,跨平台可能亂碼。生產建議顯式指定編碼:
new BufferedReader(new InputStreamReader(new FileInputStream(src), "UTF-8"));
new BufferedWriter(new OutputStreamWriter(new FileOutputStream(dest), "UTF-8"));
繼承 BufferedReader,自動追蹤行號:
setLineNumber(int) / getLineNumber():設定/獲取當前行號(預設從 0 開始)。BufferedReader/Writer 是典型的裝飾者模式應用:
Reader/Writer 抽象介面。FileReader/FileWriter 基礎實現。BufferedReader/Writer 持有 Component 引用,構造器注入。優勢:比繼承靈活,避免類爆炸;可動態組合(如 new BufferedReader(new InputStreamReader(...))),單一職責,開閉原則。
public class KeyboardToFile {
public static void main(String[] args) throws IOException {
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"))) {
String line;
while ((line = br.readLine()) != null) {
if ("exit".equalsIgnoreCase(line)) break;
bw.write(line.toUpperCase());
bw.newLine();
}
}
}
}
BufferedReader.readLine() 是按行處理文本的利器,配合 BufferedWriter.newLine() 實現跨平台換行。try-with-resources 確保資源釋放,顯式指定編碼(UTF-8)避免亂碼。InputStreamReader/OutputStreamWriter 處理編碼轉換,BufferedReader/Writer 提升效率,構建健壯 IO 處理鏈路。