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

Java 讀取文本文件最佳實踐:BufferedReader、編碼處理與資源管理

     編輯:Java 相關知識

核心 API 體系

Java I/O 按「裝飾者模式」層層包裝:

File → FileInputStream (字節流)
    → InputStreamReader (字節→字符,指定編碼)
    → BufferedReader (緩衝,按行讀取)

標準讀取範本

public static List<String> readLines(String filePath, String encoding) throws IOException {
    List<String> lines = new ArrayList<>();
    // try-with-resources 自動關閉資源 (JDK 7+)
    try (BufferedReader reader = new BufferedReader(
            new InputStreamReader(new FileInputStream(filePath), encoding))) {

        String line;
        while ((line = reader.readLine()) != null) {
            lines.add(line);
        }
    }
    return lines;
}

關鍵細節深度解析

1. 編碼指定的重要性

  • 系統默認編碼:Windows (GBK)、Linux/Mac (UTF-8)
  • 生產環境必須顯式指定:StandardCharsets.UTF_8 或 "UTF-8"
  • 未知編碼文件可用 juniversalchardet 或 Apache Tika 自動檢測

2. 大文件分塊處理

避免一次性 readAllLines() 導致 OOM:

try (Stream<String> stream = Files.lines(Paths.get(filePath), StandardCharsets.UTF_8)) {
    stream.forEach(line -> {
        // 流式處理每行,不佔用全量內存
        processLine(line);
    });
}

3. NIO.2 現代寫法

// 一次性讀取小文件
List<String> lines = Files.readAllLines(Paths.get(filePath), StandardCharsets.UTF_8);

// 寫入文件
Files.write(Paths.get(outPath), lines, StandardCharsets.UTF_8,
            StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);

4. 常見陷阱與解決

問題原因解決
中文亂碼編碼不匹配顯式指定 UTF-8/GBK,統一項目編碼
最後一行無換行符丟失readLine() 不包含換行符非行結構數據用 read(char[]) 或 Files.readString()
資源洩漏異常拋出前未 close必須使用 try-with-resources
BOM 頭干擾UTF-8 with BOM讀取首行時檢查並移除 \uFEFF

完整工具類封裝

public final class FileUtils {
    private FileUtils() {}

    public static List<String> readLines(File file, Charset charset) throws IOException {
        if (!file.exists() || !file.isFile()) throw new FileNotFoundException(file.getAbsolutePath());
        try (BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(file), charset))) {
            return r.lines().collect(Collectors.toList());
        }
    }

    public static String readAll(File file, Charset charset) throws IOException {
        return Files.readString(file.toPath(), charset);
    }

    public static void writeLines(File file, Collection<String> lines, Charset charset) throws IOException {
        Files.write(file.toPath(), lines, charset, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
    }
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved