Як зазначають інші відповіді, тимчасові файли, створені за допомогою 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.
Однак у будь-якому випадку тимчасовий файл не повинен залишатися на диску після закінчення програми.
Ps. Під час тестування цього коду в Windows я помітив досить дивовижний факт: очевидно, досить залишити тимчасовий файл незакритим, щоб уникнути його видалення . Звичайно, це також означає, що будь-який збій, який трапиться під час використання тимчасового файлу, призведе до того, що він залишиться не видаленим, і саме цього ми намагаємось уникнути тут.
AFAIK, єдиний спосіб уникнути цього - забезпечити, щоб тимчасовий файл завжди закривався за допомогою finally
блоку. Звичайно, тоді ви можете так само видалити файл у тому ж finally
блоці. Я не впевнений, що, якщо що, використання .deleteOnExit()
насправді виграє вас від цього.