方式一:FileWriter(字元流,預設覆蓋)
// 覆蓋寫入
try (FileWriter fw = new FileWriter("out.txt")) {
fw.write("Hello");
}
// 附加模式:第二參數 true
try (FileWriter fw = new FileWriter("out.txt", true)) {
fw.write("\nAppend line");
}
- 直接寫入字串/字元,內部使用預設字元集編碼。
- 適合小檔案、簡單文字寫入。
方式二:BufferedWriter(緩衝字元流,高效)
try (FileWriter fw = new FileWriter("out.txt");
BufferedWriter bw = new BufferedWriter(fw)) {
bw.write("Line 1");
bw.newLine(); // 跨平台換行
bw.write("Line 2");
}
- 預設 8KB 緩衝,減少系統呼叫,大量寫入效能遠優於裸 FileWriter。
- 提供
newLine() 自動處理平台換行符。
方式三:FileOutputStream(位元組流,處理二進位)
// 傳統寫法
FileOutputStream fos = null;
try {
fos = new FileOutputStream("data.bin");
byte[] bytes = "Binary data".getBytes(StandardCharsets.UTF_8);
fos.write(bytes);
} finally {
if (fos != null) fos.close();
}
// Java 7+ try-with-resources
try (FileOutputStream fos = new FileOutputStream("data.bin")) {
fos.write("Binary".getBytes(StandardCharsets.UTF_8));
}
- 寫入原始位元組,需自行編碼字串(
getBytes(charset))。
- 適用圖片、序列化物件、加密資料等二進位內容。
方式四:NIO Files(Java 7+,最簡潔、功能最豐富)
import java.nio.file.*;
import java.nio.charset.StandardCharsets;
import java.util.List;
// 覆蓋寫入單行/多行
Files.writeString(Paths.get("out.txt"), "Hello\nWorld", StandardCharsets.UTF_8);
Files.write(Paths.get("out.txt"), List.of("Line1","Line2"), StandardCharsets.UTF_8);
// 附加模式
Files.writeString(Paths.get("out.txt"), "\nAppend", StandardCharsets.UTF_8,
StandardOpenOption.CREATE, StandardOpenOption.APPEND);
// 二進位
Files.write(Paths.get("data.bin"), new byte[]{1,2,3},
StandardOpenOption.CREATE, StandardOpenOption.WRITE);
- 靜態方法一行搞定,自動管理資源、支援路徑操作、屬性讀寫、符號連結。
StandardOpenOption 組合控制建立、附加、截斷、同步寫入等行為。
- 支援非同步通道(
AsynchronousFileChannel)高併發場景。
效能與選擇建議
| 場景 | 推薦 | 理由 |
| 小型文字檔、簡單邏輯 | Files.writeString | 程式碼最少、自動關閉、編碼明確 |
| 大量文字逐行寫入 | BufferedWriter | 緩衝減少 I/O、newLine() 跨平台 |
| 二進位檔案(圖片、序列化) | FileOutputStream / Files.write | 直接操作 byte[] |
| 需精確控制開啟模式(同步、附加、建立父目錄) | Files.write + OpenOption | 選項組合靈活 |
| 超大檔案、非阻塞 | AsynchronousFileChannel | 配合 CompletionHandler/Future |
常見陷阱提醒
- 忘記指定
Charset 導致跨平台亂碼——永遠顯式指定 StandardCharsets.UTF_8。
- FileWriter 建構子拋出
IOException 需捕獲或拋出。
- 附加模式下若父目錄不存在會失敗,NIO 可加
CREATE 選項自動建立。
- 大量寫入未使用緩衝導致效能極差——務必包裝
BufferedWriter 或用 NIO 批次寫入。