Как отмечают другие ответы, временные файлы, созданные с помощью File.createTempFile()
, не будут удалены автоматически, если вы явно не запросите это.
Родовой, переносимый способ сделать это , чтобы позвонить .deleteOnExit()
на File
объект, который будет планировать файл для удаления , когда виртуальная машина завершается. Однако небольшой недостаток этого метода заключается в том, что он работает только при нормальном завершении работы виртуальной машины; при аварийном завершении (например, сбое виртуальной машины или принудительное завершение процесса виртуальной машины) файл может остаться восстановленным.
В системах Unixish (таких как Linux) действительно можно получить несколько более надежное решение, удалив временный файл сразу после его открытия . Это работает, потому что файловые системы Unix позволяют удалить файл ( если быть точным, отсоединить его), пока он остается открытым одним или несколькими процессами. К таким файлам можно получить доступ через открытый дескриптор файла, и пространство, которое они занимают на диске, будет освобождено ОС только после выхода последнего процесса, удерживающего открытый дескриптор файла.
Итак, вот самый надежный и переносимый способ, который я знаю, чтобы гарантировать, что временный файл будет правильно удален после выхода из программы:
import java.io.File;
import java.io.RandomAccessFile;
import java.io.IOException;
public class TempFileTest
{
public static void main(String[] args)
{
try {
File temp = File.createTempFile("tempfiletest", ".tmp");
String path = temp.getAbsolutePath();
System.err.println("Temp file created: " + path);
RandomAccessFile fh = new RandomAccessFile (temp, "rw");
System.err.println("Temp file opened for random access.");
boolean deleted = false;
try {
deleted = temp.delete();
} catch (SecurityException e) {
}
if (deleted) {
System.err.println("Temp file deleted.");
} else {
temp.deleteOnExit();
System.err.println("Temp file scheduled for deletion.");
}
try {
String str = "A quick brown fox jumps over the lazy dog.";
fh.writeUTF(str);
System.err.println("Wrote: " + str);
fh.seek(0);
String out = fh.readUTF();
System.err.println("Read: " + out);
} finally {
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()
действительно поможет вам в этом.