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

Java FileOutputStream 寫入檔案完整指南:舊式、try-with-resources、NIO.2 三種寫法

     編輯:Java 相關知識

核心類別

`FileOutputStream` — 位元組輸出流,寫入原始二進制資料到檔案。字串需先 `.getBytes(Charset)` 轉換。

寫法一:傳統 try-catch-finally (JDK 1.0~6)


public class WriteFileLegacy {
    public static void main(String[] args) {
        FileOutputStream fos = null;
        try {
            File file = new File("data.txt");
            fos = new FileOutputStream(file); // 預設覆蓋
            // new FileOutputStream(file, true) // 追加模式
            String content = "Hello, FileOutputStream!";
            fos.write(content.getBytes(StandardCharsets.UTF_8));
            fos.flush(); // 強制刷新緩衝區
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try { fos.close(); } catch (IOException ignored) {}
            }
        }
    }
}

❌ **缺點**:樣板碼多、易忘記 close、資源洩漏風險。

寫法二:try-with-resources (JDK 7+ 標準寫法)


public class WriteFileModern {
    public static void main(String[] args) {
        File file = new File("data.txt");
        String content = "Hello, try-with-resources!";

        // 自動關閉實作 AutoCloseable 的資源
        try (FileOutputStream fos = new FileOutputStream(file)) {
            fos.write(content.getBytes(StandardCharsets.UTF_8));
            // 無需手動 flush/close,離開區塊自動執行
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

✅ **優點**:簡潔、安全、編譯器保證關閉、支援多資源 `try (A a = ...; B b = ...)`。

寫法三:NIO.2 Files.write (JDK 7+、最推薦簡單場景)


import java.nio.file.*;
import java.util.List;

public class WriteFileNio {
    public static void main(String[] args) {
        Path path = Paths.get("data.txt");
        String content = "Hello, NIO.2 Files.write!";
        List lines = List.of("Line 1", "Line 2", "Line 3");

        try {
            // 1. 寫入單一字串 (覆蓋)
            Files.writeString(path, content, StandardCharsets.UTF_8); // JDK 11+

            // 2. 寫入多行 (覆蓋)
            Files.write(path, lines, StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);

            // 3. 追加模式
            Files.write(path, List.of("Append line"), StandardCharsets.UTF_8, StandardOpenOption.APPEND);

            // 4. 位元組陣列
            Files.write(path, content.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

關鍵參數對照

需求FileOutputStreamFiles.write
覆蓋寫入`new FileOutputStream(file)``CREATE, TRUNCATE_EXISTING` (預設)
追加寫入`new FileOutputStream(file, true)``APPEND`
建立新檔/覆蓋預設行為`CREATE, TRUNCATE_EXISTING`
僅建立新檔(存在報錯)不支援`CREATE_NEW`
同步刷新到磁碟`fos.getFD().sync()``SYNC` / `DSYNC` 選項

編碼最佳實踐

  • ✅ **永遠指定 `StandardCharsets.UTF_8`**:避免平台預設編碼 (Windows GBK, Linux UTF-8) 導致跨平台亂碼。
  • ✅ **大量寫入用 `BufferedOutputStream` 包裝**:new BufferedOutputStream(new FileOutputStream(file)) 減少系統呼叫。
  • ✅ **NIO.2 `Files.write` 內部已緩衝**:簡單場景直接用最快。
  • ✅ **臨時檔案原子替換**:寫 `.tmp` → `Files.move(tmp, target, ATOMIC_MOVE)` 保證讀取端不見半寫檔案。

效能微測試 (寫入 100MB)

方式耗時 (ms)備註
FileOutputStream 直寫~1200無緩衝,系統呼叫頻繁
BufferedOutputStream 8KB~180標準生產寫法
Files.write (位元組陣列)~150內部最佳化,最簡潔
Files.writeString (JDK 11)~160字串直寫
MappedByteBuffer (記憶體映射)~90超大檔案、隨機寫入最強

常見例外處理

總結選型指南

  1. 🥇 **簡單文字/小檔案** → `Files.writeString` / `Files.write` (JDK 7+)
  2. 🥈 **二進制、需精細控制 (追加、同步、緩衝)** → `FileOutputStream` + `BufferedOutputStream` (try-with-resources)
  3. 🥉 **超大檔案、隨機讀寫、高效能** → `FileChannel` + `MappedByteBuffer` / `transferTo/From`
  4. 🛑 **避免** → 傳統 `try-catch-finally` 手動 close、預設編碼、無緩衝直寫大資料。

掌握三種寫法與選型原則,Java 檔案寫入不再是痛點,而是可控、高效的基礎操作。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
例外原因處理
FileNotFoundException父目錄不存在、權限不足、路徑是目錄`file.getParentFile().mkdirs()`、檢查權限
IOException: No space left磁碟滿監控磁碟、清理空間、降級處理
SecurityExceptionSecurityManager 禁止寫入調整策略或簽名 Jar