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

Java IO 基石:FileReader 與 FileWriter 字元檔案流詳解

     編輯:Java 相關知識

FileReader / FileWriter 核心定位

FileReader 與 FileWriter 是 Java 針對字元檔案操作提供的便利類別,分別繼承自 InputStreamReader 與 OutputStreamWriter。它們內部封裝了 FileInputStream/FileOutputStream,預設使用平台預設字元集(Charset.defaultCharset())進行位元組與字元轉換,適合簡單文字檔案讀寫。

原始碼極簡解析

FileReader:唯讀字元檔案流

public class FileReader extends InputStreamReader {
    public FileReader(String fileName) throws FileNotFoundException {
        super(new FileInputStream(fileName));
    }
    public FileReader(File file) throws FileNotFoundException {
        super(new FileInputStream(file));
    }
    public FileReader(FileDescriptor fd) {
        super(new FileInputStream(fd));
    }
}

FileWriter:字元檔案寫入流

public class FileWriter extends OutputStreamWriter {
    public FileWriter(String fileName) throws IOException {
        super(new FileOutputStream(fileName));
    }
    public FileWriter(String fileName, boolean append) throws IOException {
        super(new FileOutputStream(fileName, append));
    }
    public FileWriter(File file) throws IOException {
        super(new FileOutputStream(file));
    }
    public FileWriter(File file, boolean append) throws IOException {
        super(new FileOutputStream(file, append));
    }
    public FileWriter(FileDescriptor fd) {
        super(new FileOutputStream(fd));
    }
}

關鍵特性與限制

特性FileReaderFileWriter
編碼指定❌ 不支援,固定使用平台預設編碼
追加模式—✅ 建構子支援 append 參數
緩衝支援❌ 無內建緩衝,需自行包裝 BufferedReader/Writer
適用場景簡單、小檔案、平台專用、編碼不敏感的文字處理

實戰範例:基本讀寫與編碼陷阱

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;

public class FileReaderWriterDemo {
    public static void main(String[] args) {
        Path path = Path.of("file_rw_demo.txt");
        
        // 寫入:使用 FileWriter(預設編碼)
        try (FileWriter fw = new FileWriter(path.toFile())) {
            fw.write("FileWriter 寫入測試\n");
            fw.write("支援中文:測試內容\n");
            fw.append("追加模式示範").append('\n');
        } catch (IOException e) { e.printStackTrace(); }
        
        // 讀取:使用 FileReader(預設編碼)
        try (FileReader fr = new FileReader(path.toFile())) {
            char[] buf = new char[64];
            int len;
            while ((len = fr.read(buf)) != -1) {
                System.out.print(new String(buf, 0, len));
            }
        } catch (IOException e) { e.printStackTrace(); }
        
        // ⚠️ 編碼陷阱示範:跨平台亂碼風險
        demonstrateEncodingTrap(path);
    }
    
    private static void demonstrateEncodingTrap(Path path) {
        String original = "編碼測試:中文內容";
        
        // 以 UTF-8 寫入
        try {
            Files.writeString(path, original, StandardCharsets.UTF_8);
        } catch (IOException e) { e.printStackTrace(); }
        
        // 用 FileReader 讀取(若平台預設非 UTF-8 會亂碼)
        try (FileReader fr = new FileReader(path.toFile())) {
            char[] buf = new char[100];
            int len = fr.read(buf);
            System.out.println("FileReader 讀取: " + new String(buf, 0, len));
        } catch (IOException e) { e.printStackTrace(); }
        
        // 正確做法:指定編碼
        try (var reader = new java.io.InputStreamReader(
                new java.io.FileInputStream(path.toFile()), StandardCharsets.UTF_8)) {
            char[] buf = new char[100];
            int len = reader.read(buf);
            System.out.println("指定 UTF-8 讀取: " + new String(buf, 0, len));
        } catch (IOException e) { e.printStackTrace(); }
    }
}

現代替代方案:NIO.2 Files API

Java 7+ 強烈建議使用 java.nio.file.Files 進行檔案讀寫,優勢顯著:

// 寫入(自動建立目錄、指定編碼、可選選項)
Files.writeString(path, content, StandardCharsets.UTF_8, 
                  StandardOpenOption.CREATE, StandardOpenOption.APPEND);

// 讀取整個檔案為字串
String content = Files.readString(path, StandardCharsets.UTF_8);

// 逐行串流處理(大檔案友善)
try (var lines = Files.lines(path, StandardCharsets.UTF_8)) {
    lines.filter(...).map(...).forEach(...);
}

// 取得 BufferedReader/Writer(指定編碼)
BufferedReader br = Files.newBufferedReader(path, StandardCharsets.UTF_8);
BufferedWriter bw = Files.newBufferedWriter(path, StandardCharsets.UTF_8);

何時仍適合使用 FileReader/FileWriter?

  • 維護舊代碼庫,無法引入 NIO 依賴
  • 極簡單的臨時腳本、測試代碼
  • 確定僅在單一平台、單一編碼環境運行
  • 教學示範字元流繼承體系

最佳實踐總結

  1. 新專案優先用 Files API:明確編碼、資源安全、功能豐富。
  2. 若必須用字元流:請包裝 InputStreamReader/OutputStreamWriter 明確指定編碼,再考慮加上 BufferedReader/Writer。
  3. 不要直接用 FileReader/FileWriter 處理跨平台資料:編碼不一致是亂碼首因。
  4. 大檔案務必緩衝:new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))。

FileReader 與 FileWriter 是 Java 早期為了簡化字元檔案操作而設計的便利類,但其編碼死鎖與無緩衝特性在現代開發中已顯不足。理解其內部委派機制與局限,能幫助你在維護舊代碼時做出正確判斷,並在新專案中果斷選擇更強大的 NIO.2 API。

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