首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 字符流深度解析:Reader/Writer 體系、編碼解碼與高效讀寫實戰

     編輯:Java 綜合教學

Java 字符流深度解析:Reader/Writer 體系、編碼解碼與高效讀寫實戰

字符流是 Java 處理文本數據的專用管道。其本質是 字節流 + 編碼/解碼器:讀取時將字節按指定字符集解碼為 char;寫入時將 char 編碼為字節。理解這一核心機制,是正確處理中文、避免亂碼、選擇高效 API 的前提。

一、 核心類架構

抽象基類關鍵實現類用途
ReaderFileReader, BufferedReader, InputStreamReader字符輸入(讀)
WriterFileWriter, BufferedWriter, OutputStreamWriter字符輸出(寫)

二、 節點流:FileReader / FileWriter

FileReader:讀取文本文件

  • 默認使用平台默認編碼(Windows GBK,Linux UTF-8),生產環境強烈建議顯式指定編碼(通過 InputStreamReader 包裝)。
  • 內部維護 1024 char 緩衝區,單次 read() 效率極低,必須配合 char[] 或 BufferedReader 使用。

FileWriter:寫入文本文件

  • 構造方法關鍵差異:
    • new FileWriter(file):覆蓋模式
    • new FileWriter(file, true):追加模式(第二參數 true)
    • new FileWriter(file, Charset.forName("UTF-8")):Java 11+ 支持顯式編碼
  • 寫入數據先進內存緩衝區,需 flush()、close() 或緩衝區滿時才落盤。
  • 文件不存在會自動創建;目錄不存在拋異常。

三、 處理流:BufferedReader / BufferedWriter(高效首選)

BufferedReader:逐行讀取神器

  • 默認 8192 char 緩衝區
  • 核心方法:readLine() 返回一行文本(不含換行符),遇文件結尾返回 null
  • 適用場景:配置文件解析、日誌分析、CSV 讀取

BufferedWriter:高效寫入 + 跨平台換行

  • newLine() 自動寫入系統行分隔符(System.lineSeparator())
  • 配合 flush() 確保數據及時落盤

四、 編碼橋樑:InputStreamReader / OutputStreamWriter

這是字節流與字符流的轉換樞紐,必須顯式指定 Charset:

// 讀取 UTF-8 文件(推薦寫法)
try (Reader reader = new InputStreamReader(new FileInputStream("data.txt"), StandardCharsets.UTF_8);
     BufferedReader br = new BufferedReader(reader)) {
    String line;
    while ((line = br.readLine()) != null) {
        process(line);
    }
}

// 寫入 GBK 文件(兼容舊系統)
try (Writer writer = new OutputStreamWriter(new FileOutputStream("legacy.txt"), "GBK");
     BufferedWriter bw = new BufferedWriter(writer)) {
    bw.write("中文內容");
    bw.newLine();
}

五、 完整代碼實戰

高效複製文本文件(保持編碼)

public class TextFileCopy {
    public static void copy(String src, String dest, String charset) throws IOException {
        try (BufferedReader br = new BufferedReader(
                     new InputStreamReader(new FileInputStream(src), charset));
             BufferedWriter bw = new BufferedWriter(
                     new OutputStreamWriter(new FileOutputStream(dest), charset))) {
            char[] buffer = new char[8192];
            int len;
            while ((len = br.read(buffer)) != -1) {
                bw.write(buffer, 0, len);
            }
        }
    }
}

逐行處理大文件(內存友好)

public class LargeFileProcessor {
    public static void processLineByLine(String filePath, String charset, LineConsumer consumer) throws IOException {
        try (BufferedReader br = new BufferedReader(
                 new InputStreamReader(new FileInputStream(filePath), charset))) {
            String line;
            while ((line = br.readLine()) != null) {
                consumer.accept(line);
            }
        }
    }
    @FunctionalInterface
    interface LineConsumer { void accept(String line); }
}

六、 字節流 vs 字符流:選擇決策樹

  1. 數據是否為純文本(TXT、JSON、XML、CSV、代碼)?
    • 是 → 字符流(Reader/Writer)
  2. 數據是否為二進制(圖片、視頻、音頻、壓縮包、PDF、Office 文檔)?
    • 是 → 字節流(InputStream/OutputStream)
  3. 不確定 → 字節流(通用性更強,字符流會嘗試解碼導致數據損壞)

七、 避坑清單

  • ❌ FileReader/FileWriter 不指定編碼 → 跨平台亂碼
  • ❌ 用字符流複製圖片 → 解碼失敗導致數據丟失(見《Java IO流 複製圖片》)
  • ❌ 單字符 read()/write() 循環 → 效率極低,必須用緩衝區或 Buffered 流
  • ✅ Java 7+ try-with-resources 自動關閉 → 防止資源洩漏
  • ✅ 大文件用 BufferedReader.readLine() 流式處理 → 避免 OOM

掌握字符流的編碼本質、緩衝機制與 API 選型,是 Java 開發者處理文本數據的基本功。下一篇將深入剖析 PrintWriter、StringWriter 等特殊字符流的應用場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved