メソッドを使用してJavaで一時ファイルを作成するとします。
File tmp = File.createTempFile(prefix, suffix);
delete()
メソッドを明示的に呼び出さない場合、ファイルはいつ削除されますか?
直感的には、JVMが終了したとき、またはそれ以前(ガベージコレクターによる)、または後で(オペレーティングシステムのスイーププロセスによる)可能性があります。
メソッドを使用してJavaで一時ファイルを作成するとします。
File tmp = File.createTempFile(prefix, suffix);
delete()
メソッドを明示的に呼び出さない場合、ファイルはいつ削除されますか?
直感的には、JVMが終了したとき、またはそれ以前(ガベージコレクターによる)、または後で(オペレーティングシステムのスイーププロセスによる)可能性があります。
回答:
ファイルはJavaDocから自動的に削除されません:
このメソッドは、一時ファイル機能の一部のみを提供します。このメソッドで作成されたファイルが自動的に削除されるようにするには、deleteOnExit()メソッドを使用します。
したがって、deleteOnExit()を明示的に呼び出す必要があります。
仮想マシンの終了時に、この抽象パス名で示されるファイルまたはディレクトリを削除するように要求します。
他の回答のノート、で作成した一時ファイルとして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()
実際に何が得られるかはわかりません。
deleteOnExit()
は、頻繁に呼び出されると(たとえば、多くの新しい一時ファイルを使用するシステムで)、メモリリークが発生する可能性があることです(必要なすべてのパスを記憶する必要があるため)。削除)。
from:Javaで一時ファイルを削除する方法
一時ファイルは、重要度の低い一時データを保存するために使用されます。このデータは、 システムの終了時に常に削除する必要があります。ベストプラクティスは、File.deleteOnExit()を使用して実行することです。
例えば、
File temp = File.createTempFile("abc", ".tmp");
temp.deleteOnExit();
上記の例では、「abc.tmp」という名前の一時ファイルを作成し、プログラムが終了または終了したときにそれを削除しますます。
一時ファイルを手動で削除する場合でも、File.delete()を使用できます。
必要に応じて、プロセスを終了する前にファイルを手動で削除できますが、プロセスが終了すると、ファイルも削除されます。
deleteOnExit()