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

Java 文字檔案操作完全指南:Reader/Writer 體系深度解析

     編輯:Java 相關知識

早期 Java 僅支援位元組流處理二進位檔案,為了處理字元資料,JDK 1.1 引入了以 Reader 和 Writer 為根的字元流體系。本文系統梳理字元流核心類別、編碼轉換機制、緩衝優化策略,並提供完整實戰範例,助你掌握文字檔案讀寫的最佳實踐。

字元流架構核心

Reader 與 Writer 均為抽象類別,定義了字元流操作的標準契約:

  • Writer 核心抽象方法:write(char[] cbuf, int off, int len)、flush()、close()
  • Reader 核心抽象方法:read(char[] cbuf, int off, int len)、close()

所有具體實作類別(FileReader、BufferedReader 等)必須實作這些方法。

關鍵橋樑:InputStreamReader 與 OutputStreamWriter

這兩個類別是「位元組流」與「字元流」的轉換樞紐:

  • InputStreamReader:將位元組輸入流轉換為字元輸入流,構造子可指定字元編碼(預設使用作業系統預設編碼,如中文 Windows 的 GBK/Big5)
  • OutputStreamWriter:將字元輸出流轉換為位元組輸出流,同樣支援編碼指定

關鍵洞見:FileReader 實際上繼承自 InputStreamReader,其內部預設使用系統預設編碼,跨平台時易產生亂碼,生產環境強烈建議顯式指定編碼。

讀取文字檔案的三種主流方式

1. 基礎單字元讀取(效率最低)

FileReader fr = new FileReader("ming.txt");
int ch;
while ((ch = fr.read()) != -1) {
    System.out.print((char) ch);
}

2. 指定編碼的單字元讀取

InputStreamReader isr = new InputStreamReader(new FileInputStream("ming.txt"), "UTF-8");
int ch;
while ((ch = isr.read()) != -1) {
    System.out.print((char) ch);
}

3. 緩衝逐行讀取(生產環境首選)

BufferedReader br = new BufferedReader(
    new InputStreamReader(new FileInputStream("ming.txt"), "UTF-8"));
String line;
while ((line = br.readLine()) != null) {
    System.out.println(line);
}

效能優勢:BufferedReader 內部維護字元緩衝區(預設 8192 字元),大幅減少底層 I/O 系統呼叫次數,readLine() 更適合處理行導向文字資料。

寫入文字檔案的三種對應方式

1. 基礎 FileWriter

FileWriter fw = new FileWriter("hello.txt");
String s = "hello world";
fw.write(s, 0, s.length());
fw.flush(); // 強制刷新緩衝區

2. 指定編碼 OutputStreamWriter

OutputStreamWriter osw = new OutputStreamWriter(
    new FileOutputStream("hello2.txt"), "UTF-8");
osw.write(s, 0, s.length());
osw.flush();

3. 功能增強 PrintWriter

// 第二個參數 true 表示啟用自動刷新(println/printf/format 後自動 flush)
PrintWriter pw = new PrintWriter(
    new OutputStreamWriter(new FileOutputStream("hello3.txt"), "UTF-8"), true);
pw.println(s); // 自動換行並刷新

完整整合範例:多種讀寫方式對比演示

import java.io.*;

public class TextFileDemo {
    public static void main(String[] args) {
        String testFile = "ming.txt";
        String content = "hello world i like java language";
        
        // 先建立測試檔案
        try (PrintWriter pw = new PrintWriter(testFile, "UTF-8")) {
            pw.println(content);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 方式1:FileReader 單字元讀取
        System.out.println("=== FileReader 讀取 ===");
        try (FileReader fr = new FileReader(testFile)) {
            int ch;
            while ((ch = fr.read()) != -1) System.out.print((char) ch);
        } catch (IOException e) { e.printStackTrace(); }

        // 方式2:InputStreamReader 指定編碼
        System.out.println("\n=== InputStreamReader 讀取 ===");
        try (InputStreamReader isr = new InputStreamReader(new FileInputStream(testFile), "UTF-8")) {
            int ch;
            while ((ch = isr.read()) != -1) System.out.print((char) ch);
        } catch (IOException e) { e.printStackTrace(); }

        // 方式3:BufferedReader 逐行讀取(推薦)
        System.out.println("\n=== BufferedReader 逐行讀取 ===");
        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(new FileInputStream(testFile), "UTF-8"))) {
            String line;
            while ((line = br.readLine()) != null) System.out.println(line);
        } catch (IOException e) { e.printStackTrace(); }

        // 寫入示範
        System.out.println("\n=== 寫入操作示範 ===");
        try (FileWriter fw = new FileWriter("out1.txt");
             OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("out2.txt"), "UTF-8");
             PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("out3.txt"), "UTF-8"), true)) {
            
            fw.write(content); fw.flush();
            osw.write(content); osw.flush();
            pw.println(content); // 自動 flush
            
        } catch (IOException e) { e.printStackTrace(); }
    }
}

關鍵最佳實踐總結

  1. 永遠指定編碼:避免跨平台亂碼,統一使用 UTF-8
  2. 優先使用 BufferedReader/BufferedWriter:緩衝機制大幅提升 I/O 效能
  3. 善用 try-with-resources (JDK 7+):自動關閉資源,防止洩漏
  4. 適時呼叫 flush():確保關鍵資料即時寫入磁碟
  5. 區分文字與二進位:圖片、影音等非文字資料必須使用位元組流(InputStream/OutputStream)

常見陷阱提醒

  • FileReader/FileWriter 無法指定編碼,僅適合簡單測試
  • readLine() 會捨棄換行符號,寫入時需手動添加 System.lineSeparator() 或 \\n
  • 混用位元組流與字元流操作同一檔案會導致資料損壞
  • 大檔案處理時避免一次性讀入記憶體,採用流式逐行處理

總結

Java 字元流體系透過 InputStreamReader/OutputStreamWriter 解決了位元組與字元的編碼轉換問題,配合緩衝機制提供高效能文字處理能力。掌握編碼指定、緩衝優化、資源管理三大核心要素,即能從容應對各類文字檔案處理場景。

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