CodeGym /コース /JAVA 25 SELF /一時ファイルとディレクトリの操作

一時ファイルとディレクトリの操作

JAVA 25 SELF
レベル 40 , レッスン 3
使用可能

1. 一時ファイルの作成: Files.createTempFile

一時ファイルは、中間データやキャッシュ、長期保存を前提としない結果を保持するために使われます。通常は、プログラムが動作している間、またはそのデータが不要になるまでだけ存在します。

典型的な用途としては、大きなドキュメントのダウンロード(まず一時フォルダに保存してから所定の場所へ移動)、再計算や再取得できる情報のキャッシュ、大量データ処理の途中結果の保存、プログラムの部品間やスレッド間でのデータ受け渡しなどがあります。もう一つのよくあるシナリオがテストで、作業ディレクトリを散らかさないために一時ファイルへ書く方が便利です。

一時ファイルはプログラムのための下書きのようなものだと言えます。公開用ではありませんが、これがないと作業が進まないこともあります。

Java ではこの種のファイルを作成するのはとても簡単で、実質 1 行で済みます。そのためのメソッドが 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\\<username>\\AppData\\Local\\Temp")。
  • ファイル名は "myapp_1234567890.tmp" のようになります。
  • ファイルはすでにディスク上に存在しており、通常のファイルと同様に扱えます。

メソッドの引数

  • 第1引数 — プレフィックス(例: "myapp_")。
  • 第2引数 — サフィックス(例: ".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() を使うこともできますが、これは Path ではなく File に対してのみ有効です。

例: 一時ファイルの削除

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("システムの temp フォルダ: " + 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: プロジェクトの作業ディレクトリに一時ファイルを作成する。 重要なファイルを誤って削除したり、混乱のもとになります。システムの temp フォルダやアプリ用に分けた一時フォルダを使いましょう。

エラー №5: 一時ファイルの削除時に例外を処理しない。 すでに削除済みだったりロックされている場合、削除しようとすると例外が発生することがあります。Files.deleteIfExists() と適切なエラーハンドリングを使いましょう。

コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION