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

Java 讀寫文本文件完全指南:三種核心方式、編碼控制與資源安全

     編輯:Java 程式設計入門

文本文件讀寫是 Java 開發高頻操作。本文對比 FileReader/BufferedReader、FileWriter/BufferedWriter、FileInputStream/OutputStream 三大體系,強調編碼顯式指定、try-with-resources 自動關閉、追加/覆蓋模式切換,提供可直接落地的工具方法。

方式一:字符流 + 緩衝(推薦文本讀取)

public static String readTextFile(File file, String charset) {
    if (charset == null) charset = StandardCharsets.UTF_8.name();
    if (!file.isFile() || !file.exists()) return null;

    try (BufferedReader br = new BufferedReader(
            new InputStreamReader(new FileInputStream(file), charset))) {

        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = br.readLine()) != null) {
            sb.append(line).append(System.lineSeparator());
        }
        return sb.toString();
    } catch (IOException e) {
        throw new UncheckedIOException("讀取失敗: " + file, e);
    }
}

優點:按行讀取、記憶體友好、自動處理換行符、編碼可控。
進階:大文件逐行處理(不拼接全量字符串)直接在循環內業務邏輯。

方式二:FileWriter/BufferedWriter(推薦文本寫入)

覆蓋模式

public static void writeTextFile(File file, String content, String charset) {
    writeTextFile(file, content, charset, false);
}

追加模式

public static void appendTextFile(File file, String content, String charset) {
    writeTextFile(file, content, charset, true);
}

統一實現

private static void writeTextFile(File file, String content, String charset, boolean append) {
    if (charset == null) charset = StandardCharsets.UTF_8.name();
    // 父目錄不存在自動創建
    File parent = file.getParentFile();
    if (parent != null && !parent.exists()) parent.mkdirs();

    try (BufferedWriter bw = new BufferedWriter(
            new OutputStreamWriter(new FileOutputStream(file, append), charset))) {
        bw.write(content);
    } catch (IOException e) {
        throw new UncheckedIOException("寫入失敗: " + file, e);
    }
}

關鍵點:

  • new FileOutputStream(file, true) 開啟追加模式。
  • OutputStreamWriter 顯式指定編碼,避免 FileWriter 隱式平台編碼。
  • file.createNewFile() 非必需,FileOutputStream 會自動創建文件。

方式三:字節流(適用二進制或已編碼字節數組)

public static void writeBytes(File file, byte[] data) {
    File parent = file.getParentFile();
    if (parent != null && !parent.exists()) parent.mkdirs();

    try (FileOutputStream fos = new FileOutputStream(file)) {
        fos.write(data);
        fos.flush();
    } catch (IOException e) {
        throw new UncheckedIOException("字節寫入失敗: " + file, e);
    }
}

// 調用:writeBytes(file, "內容".getBytes(StandardCharsets.UTF_8));

現代替代方案(JDK 7+ NIO.2 / JDK 11+)

API用法優點
Files.readString(Path)String s = Files.readString(path, StandardCharsets.UTF_8);一行代碼讀全文,自動關閉
Files.writeString(Path, CharSequence, OpenOption...)Files.writeString(path, content, StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.APPEND);一行寫入/追加,原子性選項
Files.lines(Path)try (Stream<String> lines = Files.lines(path)) { lines.forEach(...); }流式逐行處理,自動關閉
Files.newBufferedReader/Writer(Path, Charset)返回 BufferedReader/Writer兼容舊代碼風格,資源安全

最佳實踐清單

  1. 統一 UTF-8:構造函數、StandardCharsets.UTF_8 顯式傳遞。
  2. try-with-resources:所有流/Reader/Writer/Channel 必須包裹,保證異常時也關閉。
  3. 父目錄自動創建:file.getParentFile().mkdirs() 防 FileNotFoundException。
  4. 大文件勿一次性讀入內存:用 Files.lines() 流式處理或逐行業務邏輯。
  5. 關鍵日誌同步落盤:flush() 或 StandardOpenOption.SYNC(性能權衡)。
  6. 異常包裝:拋出 UncheckedIOException 保持調用鏈簡潔,上層統一處理。

總結

文本讀寫首選 NIO.2 Files 靜態方法(JDK 11+ 最簡潔),舊版本用 字符流 + 緩衝 + 顯式編碼 + try-with-resources。字節流僅用於已編碼的 byte[] 或二進制數據。牢記「編碼顯式、資源自動、大文件流式」三原則,杜絕亂碼與泄漏。

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