Java一時ファイルはいつ削除されますか?


92

メソッドを使用してJavaで一時ファイルを作成するとします。

File tmp = File.createTempFile(prefix, suffix);

delete()メソッドを明示的に呼び出さない場合、ファイルはいつ削除されますか?

直感的には、JVMが終了したとき、またはそれ以前(ガベージコレクターによる)、または後で(オペレーティングシステムのスイーププロセスによる)可能性があります。



申し訳ありませんが、メソッドdocs.oracle.com/javase/6/docs/api/java/io/…のみを確認しましたが、答えは提供されていません。長い説明は、署名が長いメソッドにのみ存在します。
alphaaa 2013年

回答:


95

ファイルはJavaDocから自動的に削除されません:

このメソッドは、一時ファイル機能の一部のみを提供します。このメソッドで作成されたファイルが自動的に削除されるようにするには、deleteOnExit()メソッドを使用します。

したがって、deleteOnExit()を明示的に呼び出す必要があります。

仮想マシンの終了時に、この抽象パス名で示されるファイルまたはディレクトリを削除するように要求します。


2
また、deleteOnExitを使用すると、「仮想マシンの終了時に削除されます。ファイル(またはディレクトリ)は、登録されているのと逆の順序で削除されます。このメソッドを呼び出して、すでに削除登録されているファイルまたはディレクトリを削除することはできません。効果。削除は、Java言語仕様で定義されているように、仮想マシンの通常の終了に対してのみ試行されます。」そのため、すべてのJVMが存在しても削除されません。
eis 2013年

おかげで、私はメソッドdocs.oracle.com/javase/6/docs/api/java/io/…をチェックしただけで、答えは提供されません。長い説明は、署名が長いメソッドにのみ存在します
Alphaaa 2013年

52

他の回答のノート、で作成した一時ファイルとしてFile.createTempFile()意志ではありません、あなたが明示的に要求しない限り、自動的に削除されます。

これを行うための一般的でポータブルな方法は.deleteOnExit()Fileオブジェクトにより、JVMの終了時にファイルが削除されるようにスケジュールされます。ただし、この方法のわずかな欠点は、VMが正常に終了した場合にのみ機能することです。異常終了(つまり、VMのクラッシュまたはVMプロセスの強制終了)が発生した場合、ファイルは削除されないままになる可能性があります。

Unixのシステム(Linuxなど)では、一時ファイルを開いた直後に削除することで、より信頼性の高いソリューションを実際に取得できます。これは、Unixファイルシステムでファイルを削除(リンク解除)できるためです。 1つ以上のプロセスによって開いたままの状態で正確には)。このようなファイルには通常、開いているファイルハンドルを介してアクセスでき、ディスク上でそれらが占めるスペースは、ファイルの開いているハンドルを保持している最後のプロセスが終了した後にのみOSによって再利用されます。

したがって、プログラムの終了後に一時ファイルが適切に削除されるようにするための、最も信頼性が高く移植性の高い方法は次のとおりです。

import java.io.File;
import java.io.RandomAccessFile;
import java.io.IOException;

public class TempFileTest
{
    public static void main(String[] args)
    {
        try {
            // create a temp file
            File temp = File.createTempFile("tempfiletest", ".tmp"); 
            String path = temp.getAbsolutePath();
            System.err.println("Temp file created: " + path);

            // open a handle to it
            RandomAccessFile fh = new RandomAccessFile (temp, "rw");
            System.err.println("Temp file opened for random access.");

            // try to delete the file immediately
            boolean deleted = false;
            try {
                deleted = temp.delete();
            } catch (SecurityException e) {
                // ignore
            }

            // else delete the file when the program ends
            if (deleted) {
                System.err.println("Temp file deleted.");
            } else {
                temp.deleteOnExit();
                System.err.println("Temp file scheduled for deletion.");
            }

            try {
                // test writing data to the file
                String str = "A quick brown fox jumps over the lazy dog.";
                fh.writeUTF(str);
                System.err.println("Wrote: " + str);

                // test reading the data back from the file
                fh.seek(0);
                String out = fh.readUTF();
                System.err.println("Read: " + out);

            } finally {
                // close the file
                fh.close();
                System.err.println("Temp file closed.");
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Unixishシステムでは、これを実行すると、次のような出力が生成されます。

Temp file created: /tmp/tempfiletest587200103465311579.tmp
Temp file opened for random access.
Temp file deleted.
Wrote: A quick brown fox jumps over the lazy dog.
Read: A quick brown fox jumps over the lazy dog.
Temp file closed.

一方、Windowsでは、出力はわずかに異なります。

Temp file created: C:\DOCUME~1\User\LOCALS~1\Temp\tempfiletest5547070005699628548.tmp
Temp file opened for random access.
Temp file scheduled for deletion.
Wrote: A quick brown fox jumps over the lazy dog.
Read: A quick brown fox jumps over the lazy dog.
Temp file closed.

ただし、いずれの場合も、プログラムの終了後に一時ファイルをディスクに残してはなりません。


追伸 このコードをWindowsでテストしているときに、かなり驚くべき事実を観察しました。明らかに、一時ファイルを閉じないままにしておくだけで、削除されないようにすることができます。もちろん、これは、一時ファイルの使用中にクラッシュが発生すると、ファイルが削除されないままになることも意味します。これは、まさにここで回避しようとしていることです。

AFAIK、これを回避する唯一の方法は、一時ファイルが常にfinallyブロックを使用して閉じられるようにすることです。もちろん、同じfinallyブロック内のファイルを削除することもできます。どちらを使用しても、.deleteOnExit()実際に何が得られるかはわかりません。


1
素晴らしい答え。注意すべきもう1つの重要な点deleteOnExit()は、頻繁に呼び出されると(たとえば、多くの新しい一時ファイルを使用するシステムで)、メモリリークが発生する可能性があることです(必要なすべてのパスを記憶する必要があるため)。削除)。
Eyal Roth

18

delete()メソッドを明示的に呼び出さない場合、ファイルはいつ削除されますか?

少なくともJavaではそうではありません。JVMの終了時にファイルを削除する場合は、を呼び出す必要がありますtmp.deleteOnExit()


5

from:Javaで一時ファイルを削除する方法

一時ファイルは、重要度の低い一時データを保存するために使用されます。このデータは、 システムの終了時に常に削除する必要があります。ベストプラクティスは、File.deleteOnExit()を使用して実行することです。

例えば、

File temp = File.createTempFile("abc", ".tmp"); 
temp.deleteOnExit();

上記の例では、「abc.tmp」という名前の一時ファイルを作成し、プログラムが終了または終了したときにそれ削除しますます。

一時ファイルを手動で削除する場合でも、File.delete()を使用できます。


なぜこれがベストプラクティスなのですか?
Frans 2018年

3

一時ファイルは、重要度の低い一時データを保存するために使用されます。このデータは、システムが終了したときに常に削除する必要があります。ベストプラクティスは、File.deleteOnExit()を使用して実行することです。

例えば、

File temp = File.createTempFile("abc", ".tmp"); 
temp.deleteOnExit();

上記の例では、「abc.tmp」という名前の一時ファイルを作成し、プログラムが終了または終了したときにそれを削除します。


-3

必要に応じて、プロセスを終了する前にファイルを手動で削除できますが、プロセスが終了すると、ファイルも削除されます。


3
いいえ、特に電話をかけた場合にのみ、終了時に削除されますdeleteOnExit()
Ian Roberts
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.