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

Java 文本文件讀寫完整實戰:創建、追加、讀取與資源管理最佳實踐

     編輯:Java 程式設計入門

文本文件讀寫是 Java 基礎且高頻操作,正確處理字符編碼、資源關閉、異常安全、大文件效能是生產代碼必備素質。本文提供完整工具類實作,涵蓋創建、追加寫入、多種讀取方式,並對比傳統 IO 與 NIO.2 現代 API。

傳統 IO 完整工具類 (JDK 1.4+ 兼容)


package com.b510.txt;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;

/**
 * 文本文件操作工具類
 * 線程不安全,多線程環境需外部同步或使用 ThreadLocal
 */
public class MyFile {
    private static final String DEFAULT_DIR = "txt/";
    private static String currentFilePath;

    public static void main(String[] args) throws IOException {
        MyFile tool = new MyFile();
        for (int i = 0; i < 5; i++) {
            tool.createTxtFile("test");
            tool.writeTxtFile("顯示的是追加的信息" + i);
            System.out.println("*********\n" + tool.readAllText());
        }
    }

    /** 創建文件(含父目錄),返回是否新建 */
    public static boolean createTxtFile(String name) throws IOException {
        Path dir = Paths.get(DEFAULT_DIR);
        Files.createDirectories(dir); // 自動創建多級目錄
        Path file = dir.resolve(name + ".txt");
        currentFilePath = file.toString();
        return Files.notExists(file) && Files.createFile(file) != null;
    }

    /** 追加寫入 (自動換行),指定 UTF-8 編碼 */
    public static boolean writeTxtFile(String newStr) throws IOException {
        if (currentFilePath == null) throw new IllegalStateException("請先調用 createTxtFile");
        Path file = Paths.get(currentFilePath);
        // 追加模式、創建不存在、UTF-8
        Files.write(file, (newStr + System.lineSeparator()).getBytes(StandardCharsets.UTF_8),
                StandardOpenOption.CREATE, StandardOpenOption.APPEND);
        return true;
    }

    /** 讀取全部內容為單一字符串 (小文件適用) */
    public String readAllText() throws IOException {
        if (currentFilePath == null) return "";
        return Files.readString(Paths.get(currentFilePath), StandardCharsets.UTF_8);
    }

    /** 按行讀取 (大文件、流式處理) */
    public void readLines(Consumer<String> lineHandler) throws IOException {
        if (currentFilePath == null) return;
        try (BufferedReader br = Files.newBufferedReader(Paths.get(currentFilePath), StandardCharsets.UTF_8)) {
            String line;
            while ((line = br.readLine()) != null) lineHandler.accept(line);
        }
    }

    // ===== 以下為傳統 IO 寫法 (教學參考) =====
    @Deprecated
    public static boolean writeTxtFileLegacy(String newStr) throws IOException {
        if (currentFilePath == null) throw new IllegalStateException("未初始化文件");
        File file = new File(currentFilePath);
        StringBuilder buf = new StringBuilder();
        // 讀取原內容
        try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) {
            String line;
            while ((line = br.readLine()) != null) buf.append(line).append(System.lineSeparator());
        }
        buf.append(newStr).append(System.lineSeparator());
        // 寫入
        try (PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) {
            pw.write(buf.toString());
        }
        return true;
    }
}

關鍵最佳實踐對比

編碼處理鐵律

  1. 顯式指定編碼:StandardCharsets.UTF_8,絕不依賴平台預設 (GBK/CP1252)
  2. 跨平台換行:System.lineSeparator() (Win \r\n, Unix \n)
  3. BOM 處理:UTF-8 通常無 BOM,若需寫入 BOM:Files.write(path, new byte[]{(byte)0xEF,(byte)0xBB,(byte)0xBF}, CREATE)

資源管理:try-with-resources (JDK 7+)


// ✅ 自動關閉、異常安全、抑制異常鏈
try (BufferedReader br = Files.newBufferedReader(path, UTF_8);
     BufferedWriter bw = Files.newBufferedWriter(outPath, UTF_8, APPEND)) {
    String line;
    while ((line = br.readLine()) != null) {
        bw.write(process(line));
        bw.newLine();
    }
} // 編譯器自動生成 finally 關閉邏輯

效能優化建議

  • 大文件複製:Files.copy(src, dst, StandardCopyOption.REPLACE_EXISTING) (OS 層面零拷貝)
  • 內存映射:FileChannel.map(MapMode.READ_ONLY, 0, size) (隨機訪問、超大文件)
  • 並行處理:Files.lines(path).parallelStream().forEach(...) (CPU 密集型行處理)
  • 緩衝區大小:默認 8KB,大順序讀寫可調大:new BufferedInputStream(is, 64*1024)

常見坑點排查

場景推薦 API (NIO.2)傳統 IO 寫法核心優勢
小文件全讀Files.readString(path, charset)BufferedReader 循環單行、自動關閉、編碼顯式
小文件全寫/追加Files.write(path, bytes, APPEND)FileOutputStream + PrintWriter原子選項、自動刷新、無需手動 close
大文件流式讀取Files.newBufferedReader(path) + try-with-resourcesBufferedReader + 手動 close資源自動管理、異常安全
大文件流式寫入Files.newBufferedWriter(path, APPEND)PrintWriter + 手動 flush/close緩衝自動、編碼統一
目錄/文件操作Files.createDirectories(), Files.deleteIfExists()File.mkdirs(), file.delete()異常信息豐富、符號鏈接感知
現象原因解決
中文亂碼讀寫編碼不一致、或用平台預設編碼全鏈路顯式 StandardCharsets.UTF_8
內容被截斷未 flush/close、緩衝區未寫入磁碟try-with-resources 自動關閉刷新
FileNotFoundException父目錄不存在、路徑分隔符錯誤Files.createDirectories(parent)、Paths.get()
併發寫入丟數據多線程同時 Append 無同步文件鎖 FileChannel.lock()、或單線程寫入隊列
大文件 OOMreadAllBytes/readString 載入整文件流式處理 Files.lines()/newBufferedReader()

總結

現代 Java (JDK 7+) 應優先使用 java.nio.file.Files 靜態方法配合 try-with-resources,實現編碼顯式、資源自動管理、異常安全、代碼簡潔。傳統 java.io 僅用於維護舊代碼或特殊場景 (如需要 RandomAccessFile 隨機讀寫)。掌握 NIO.2 核心 API 是寫出健壯文件操作代碼的基石。

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