CodeGym /課程 /JAVA 25 SELF /處理暫存檔案與目錄

處理暫存檔案與目錄

JAVA 25 SELF
等級 40 , 課堂 3
開放

1. 建立暫存檔案:Files.createTempFile

暫存檔案用於保存中間資料、快取,或任何不打算長期保存的結果。通常它們只在程式執行期間存在,或直到這些資料不再需要為止.

常見情境包括:下載大型檔案時先放在暫存資料夾再移動到目標位置;對可重新計算或重新取得的資訊進行快取;在處理大型資料集時保存中間結果;以及在程式各模組或執行緒之間交換資料。另一個常見情境是測試:把輸出寫到暫存檔比弄亂工作目錄來得方便。

可以把暫存檔案看作是程式的草稿。它們不是用來對外展示,但往往沒有它們就很難把工作做好。

在 Java 中建立這種檔案非常容易——幾乎只要一行程式碼。可以使用方法 Files.createTempFile.

簡單範例

import java.nio.file.*;

public class TempFileExample {
    public static void main(String[] args) throws Exception {
        // 建立前綴為 "myapp_"、後綴為 ".tmp" 的暫存檔案
        Path tempFile = Files.createTempFile("myapp_", ".tmp");
        System.out.println("已建立暫存檔案:" + tempFile);

        // 可以寫入資料
        Files.writeString(tempFile, "這是暫存資料");

        // 讀回資料
        String data = Files.readString(tempFile);
        System.out.println("內容:" + data);
    }
}

發生了什麼?

  • 檔案會建立在系統的暫存目錄中(在 Linux 通常是 "/tmp",在 Windows 則是 "C:\\Users\\<name>\\AppData\\Local\\Temp")。
  • 檔名類似於 "myapp_1234567890.tmp"
  • 檔案已實際存在於磁碟,可像一般檔案一樣操作。

方法參數

  • 第一個參數 — 前綴(例如 "myapp_")。
  • 第二個參數 — 後綴(例如 ".tmp")。若未指定,預設為 ".tmp"
  • 若兩個參數都為 null,檔名將採用預設值。

檔案會存到哪裡?

預設會存到系統暫存目錄。不過你也可以指定自訂位置:

Path tempDir = Paths.get("my_temp_folder");
Files.createDirectories(tempDir); // 若不存在則建立
Path tempFile = Files.createTempFile(tempDir, "prefix_", ".txt");

2. 建立暫存目錄:Files.createTempDirectory

有時不只需要暫存檔,而是整個暫存資料夾——例如用於解壓縮檔案或暫時存放多個檔案。

範例

import java.nio.file.*;

public class TempDirExample {
    public static void main(String[] args) throws Exception {
        // 建立前綴為 "work_" 的暫存目錄
        Path tempDir = Files.createTempDirectory("work_");
        System.out.println("暫存資料夾:" + tempDir);

        // 可以在其中建立檔案
        Path fileInTempDir = Files.createTempFile(tempDir, "file_", ".dat");
        System.out.println("其中的暫存檔案:" + fileInTempDir);
    }
}

特點:

  • 資料夾名稱大致會像這樣:"work_1234567890"
  • 預設建立在系統暫存目錄,但也可以指定任意其他位置。

指定目錄

Path baseDir = Paths.get("my_temp_work");
Files.createDirectories(baseDir);
Path tempDir = Files.createTempDirectory(baseDir, "session_");

3. 刪除暫存檔案與目錄

這裡藏著 Java 的一大「陷阱」:暫存檔與資料夾不會自動刪除!若你不主動清理,它們會一直留在磁碟上,可能多年都在,直到系統下次清理為止。

如何刪除暫存檔案?

  • 手動:在檔案使用完後呼叫 Files.delete(...) 或 Files.deleteIfExists(...)。
  • 在程式結束時:可以使用古早但實用的方法 File.deleteOnExit(),但僅適用於 File,而非 Path

範例:刪除暫存檔案

import java.nio.file.*;

public class TempFileDeleteExample {
    public static void main(String[] args) throws Exception {
        Path tempFile = Files.createTempFile("demo_", ".tmp");
        System.out.println("已建立:" + tempFile);

        // ... 進行檔案操作

        // 刪除檔案
        Files.deleteIfExists(tempFile);
        System.out.println("已刪除:" + tempFile);
    }
}

使用 deleteOnExit()

import java.io.File;

public class DeleteOnExitDemo {
    public static void main(String[] args) throws Exception {
        File tempFile = File.createTempFile("legacy_", ".tmp");
        System.out.println("已建立:" + tempFile);

        // 在 JVM 結束時標記該檔案要刪除
        tempFile.deleteOnExit();
    }
}

注意!
方法 deleteOnExit() 只適用於 File,而非 Path。如果你使用的是現代 API(PathFiles),請手動刪除。

刪除暫存目錄

只能在資料夾為空時才能刪除暫存資料夾:

Files.delete(tempDir); // 若目錄內仍有內容將拋出例外

如果資料夾內還有檔案,請先刪除它們,再刪除資料夾。通常會寫一個小型遞迴方法來完成。

4. 實用建議

暫存檔案應該放哪裡?

系統暫存目錄:
預設情況下使用它即可,除非有特殊需求。可以這樣取得路徑:

String tempDir = System.getProperty("java.io.tmpdir");
System.out.println("系統暫存資料夾:" + tempDir);

自訂資料夾:
若重視安全性或組織性,請建立專用的資料夾(例如放在應用程式目錄下)。

安全性

  • 不要把暫存檔案存放在任何人都可存取的資料夾——尤其當其中可能包含敏感資訊時。
  • 使用後請清理暫存檔案——否則它們可能不斷累積佔用空間。

發生錯誤時的清理

若程式執行過程中發生錯誤,別忘了刪除暫存檔。使用區塊 try-finally 相當方便:

Path tempFile = Files.createTempFile("task_", ".tmp");
try {
    // 使用該檔案
} finally {
    Files.deleteIfExists(tempFile);
}

暫存檔案與測試

在測試中,常用暫存檔與資料夾來隔離資料。測試結束後,務必刪除所有建立的資源!

5. 範例:用於資料處理的暫存工作目錄

假設你正在撰寫一個處理壓縮檔並暫時解壓內容的程式。可以建立一個暫存資料夾,並在完成後將其刪除。

import java.nio.file.*;
import java.io.IOException;

public class TempWorkDirExample {
    public static void main(String[] args) throws IOException {
        // 建立暫存目錄
        Path tempWorkDir = Files.createTempDirectory("unzip_");
        System.out.println("暫存工作資料夾:" + tempWorkDir);

        try {
            // 這裡可以進行解壓縮
            Path tempFile = Files.createTempFile(tempWorkDir, "file_", ".txt");
            Files.writeString(tempFile, "用於處理的暫存資料");

            // ... 處理檔案

        } finally {
            // 刪除資料夾中的所有檔案以及資料夾本身
            Files.walk(tempWorkDir)
                .sorted((a, b) -> b.compareTo(a)) // 先刪檔案,再刪資料夾
                .forEach(path -> {
                    try {
                        Files.deleteIfExists(path);
                    } catch (IOException ex) {
                        System.err.println("無法刪除 " + path + ": " + ex.getMessage());
                    }
                });
            System.out.println("已刪除暫存資料夾與檔案。");
        }
    }
}

請注意:
先刪除所有檔案,再刪除資料夾。這裡的排序是為了避免在刪除內容之前就嘗試刪除資料夾。

6. 使用暫存檔案時的常見錯誤

錯誤 1:忘記刪除暫存檔或資料夾。 這是最常見的問題——暫存檔長期留在磁碟,逐漸堆積,導致系統「變髒」。對伺服器應用與長時間執行的程序尤其嚴重。

錯誤 2:對 Path 使用 deleteOnExit() 方法 deleteOnExit() 只適用於類別 File,不適用於 Path。若使用現代 API,就必須自行刪除。

錯誤 3:嘗試透過 Files.delete 刪除非空資料夾。 方法 Files.delete() 只能刪除空目錄。若裡面仍有內容——會拋出例外。要刪除非空目錄,請先遞迴走訪並刪除所有檔案。

錯誤 4:在專案工作目錄中建立暫存檔。 這可能導致誤刪重要檔案或造成混亂。最好使用系統暫存資料夾,或為應用程式的暫存檔建立專用資料夾。

錯誤 5:刪除暫存檔時未處理例外。 若檔案已被刪除或被鎖定,刪除操作可能拋出例外。請使用 Files.deleteIfExists() 並妥善處理錯誤。

留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION