419. 現(xiàn)代 Java IO 最佳實(shí)踐 - 寫入文本文件
在應(yīng)用開發(fā)中,寫入文本文件是一個(gè)非常常見的操作?,F(xiàn)代 Java(尤其是 java.nio.file.Files API)已經(jīng)把它簡(jiǎn)化到“一行代碼”的程度。
1. ?? 寫入單個(gè)字符串
如果我們要寫入整個(gè)字符串,可以直接用:
String content = "Hello Java I/O!";
Path path = Path.of("output.txt");
Files.writeString(path, content);
? 特點(diǎn):
- 一行搞定,非常簡(jiǎn)潔。
- 會(huì)覆蓋已有文件(默認(rèn)行為)。
?? 如果想在文件末尾追加內(nèi)容,可以指定選項(xiàng):
Files.writeString(path, "追加的一行\(zhòng)n", StandardOpenOption.APPEND);
2. ?? 寫入多行文本
當(dāng)我們有一個(gè) 行列表 時(shí),可以直接寫入:
List<String> lines = List.of("第一行", "第二行", "第三行");
Files.write(Path.of("lines.txt"), lines);
效果就是每個(gè)元素寫一行。
3. ?? 使用 PrintWriter(格式化輸出)
有時(shí)我們需要 格式化輸出(例如 printf)。
String name = "Alice";
int age = 29;
try (var writer = new PrintWriter(Path.of("person.txt").toFile())) {
writer.printf(Locale.US, "Hello, %s, next year you'll be %d years old!%n", name, age + 1);
}
?? 注意:
-
printf是 與 Locale(本地化)相關(guān) 的。-
Locale.US會(huì)用點(diǎn)號(hào)作為小數(shù)點(diǎn)。 -
Locale.GERMANY會(huì)用逗號(hào)作為小數(shù)點(diǎn)。
-
- 如果不想依賴 Locale,推薦使用:
Integer.toString()Double.toString()- 或
NumberFormat
?? ?? 奇怪的是,直到 Java 21,PrintWriter 還沒有直接接受 Path 的構(gòu)造方法,所以需要先 .toFile()。
4. ?? 使用 BufferedWriter(逐行寫)
如果不用 printf,可以用 BufferedWriter:
try (var writer = Files.newBufferedWriter(Path.of("buffered.txt"))) {
writer.write("第一行");
writer.newLine(); // 手動(dòng)寫入換行符
writer.write("第二行");
}
? 特點(diǎn):
- 更靈活,可以逐行控制輸出。
- 寫入時(shí)需要手動(dòng)調(diào)用
newLine(),否則不會(huì)自動(dòng)換行。 -
try-with-resources會(huì)自動(dòng)關(guān)閉 writer。
5. ?? 總結(jié)
| 寫法 | 適用場(chǎng)景 | 示例 |
|---|---|---|
Files.writeString |
寫入單個(gè)字符串 | Files.writeString(path, content); |
Files.write |
寫入多行 | Files.write(path, lines); |
PrintWriter.printf |
格式化輸出 | writer.printf(Locale.US, "...", name, age); |
BufferedWriter |
靈活逐行寫 | writer.write(...); writer.newLine(); |
?? 課堂練習(xí)建議
- 讓學(xué)員寫一個(gè)程序,把控制臺(tái)輸入的內(nèi)容逐行寫入文件(直到輸入 "exit" 為止)。
- 用
Files.writeString實(shí)現(xiàn)一個(gè)簡(jiǎn)單的日志追加寫入功能。 - 比較
printf和NumberFormat在不同 Locale 下的輸出差異。