416. 現(xiàn)代 Java I/O 最佳實(shí)踐 - 高效、簡潔、安全地處理文本與數(shù)據(jù)

416. 現(xiàn)代 Java I/O 最佳實(shí)踐 - 高效、簡潔、安全地處理文本與數(shù)據(jù)

1. ?? 引言

在日常應(yīng)用開發(fā)(特別是 Web 應(yīng)用)中,我們經(jīng)常會(huì)遇到以下 I/O 操作:

  • 讀取/寫入文本文件
  • 從網(wǎng)絡(luò)讀取文本、圖片、JSON
  • 遍歷目錄下的文件
  • 讀取 ZIP 壓縮文件
  • 創(chuàng)建臨時(shí)文件或目錄

Java 的 I/O API 很強(qiáng)大,從 Java 7 引入的 java.nio.file.Files 一直到 Java 18UTF-8 默認(rèn)支持,給我們帶來了很多便利。

?? 需要注意的是:

  • 舊的 java.io.Filejava.io.BufferedReader 已經(jīng)過時(shí),雖然它們在搜索結(jié)果中仍然很多,但在現(xiàn)代 Java 中應(yīng)盡量避免。
  • UTF-8Java 18 之后已經(jīng)是默認(rèn)字符集(JEP 400),不用再手動(dòng)指定,大大減少了編碼問題。

2. ?? 讀取文本文件

最簡單的方式:

var path = Path.of("/usr/share/dict/words");
String content = Files.readString(path);
System.out.println(content);

?? 補(bǔ)充說明:

  • Files.readString(path) 會(huì)一次性把文件內(nèi)容讀入字符串。

  • 在 Java 18 之前,為了避免編碼問題,通常需要:

    Files.readString(path, StandardCharsets.UTF_8);
    

    但現(xiàn)在默認(rèn)就是 UTF-8,不需要再寫。


3. ?? 按行讀取文本文件

如果我們需要逐行處理:

List<String> lines = Files.readAllLines(path);

但對于 大文件,不建議一次性讀入,而是用 流式處理

try (Stream<String> lines = Files.lines(path)) {
    lines.filter(line -> line.contains("Java"))
         .forEach(System.out::println);
}

? 注意:Files.lines 返回的是 Stream<String>,需要 try-with-resources 來確保自動(dòng)關(guān)閉。

?? 不推薦再使用 BufferedReader.readLine()


4. ?? 使用 Scanner 進(jìn)行分詞讀取

有時(shí)我們需要 按單詞 拆分,而不是按行??梢杂?Scanner

try (Scanner scanner = new Scanner(path)) {
    scanner.useDelimiter("\\PL+"); // 非字母作為分隔符
    while (scanner.hasNext()) {
        System.out.println(scanner.next());
    }
}

?? 進(jìn)階寫法:直接轉(zhuǎn)成 Stream<String>

Stream<String> tokens = new Scanner(path)
        .useDelimiter("\\PL+")
        .tokens();

tokens.limit(10).forEach(System.out::println);

5. ?? 讀取數(shù)字與本地化問題

Scanner 也能讀取數(shù)字,但要注意 本地化陷阱。
比如文本中有 100.000

  • 在美國 (US) 本地化下,它表示 100.0
  • 在德國 (DE) 本地化下,它表示 100000.0

?? 如果涉及本地化,應(yīng)該使用 NumberFormat

NumberFormat nf = NumberFormat.getInstance(Locale.GERMANY);
Number num = nf.parse("100.000");
System.out.println(num); // 輸出 100000

?? 總結(jié)(課堂收尾)

  • 讀取整文件Files.readString(path)
  • 逐行處理Files.lines(path) + 流式操作
  • 分詞處理Scanner + useDelimiter
  • 數(shù)字處理:注意本地化,推薦 NumberFormat

? 從 Java 18 開始,UTF-8 已經(jīng)是默認(rèn)編碼,大部分時(shí)候不用再操心字符集問題。
?? 避免使用過時(shí)的 File、BufferedReader.readLine,用 FilesStreams 來寫現(xiàn)代化 I/O。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容