Jak zauważają inni odpowiedzi, pliki tymczasowe utworzone za pomocą nieFile.createTempFile()
będą zostać automatycznie usunięte, chyba że wyraźnie o to poproszą.
Rodzajową, przenośny sposób to zrobić, to zadzwonić .deleteOnExit()
naFile
obiekcie, który zaplanuje plik do usunięcia, gdy JVM kończy. Niewielką wadą tej metody jest jednak to, że działa ona tylko wtedy, gdy maszyna wirtualna kończy normalnie; w przypadku nieprawidłowego zakończenia (tj. awarii maszyny wirtualnej lub wymuszonego zakończenia procesu maszyny wirtualnej) plik może pozostać nieusunięty.
W systemach Unixish (takich jak Linux) w rzeczywistości możliwe jest uzyskanie nieco bardziej niezawodnego rozwiązania poprzez usunięcie pliku tymczasowego natychmiast po jego otwarciu . Działa to, ponieważ uniksowe systemy plików pozwalają na usunięcie pliku ( dokładniej mówiąc, odłączenie go), gdy jest on nadal otwarty przez jeden lub więcej procesów. Dostęp do takich plików można uzyskać normalnie przez otwarty uchwyt pliku, a miejsce, które zajmują na dysku, zostanie odzyskane przez system operacyjny dopiero po ostatnim procesie trzymającym otwarte dojście do wyjścia pliku.
Oto najbardziej niezawodny i przenośny sposób, jaki znam, aby upewnić się, że plik tymczasowy zostanie poprawnie usunięty po zamknięciu programu:
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();
}
}
}
W systemie Unixish uruchomienie tego powinno dać coś podobnego do następującego wyniku:
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.
podczas gdy w systemie Windows dane wyjściowe wyglądają nieco inaczej:
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.
Jednak w obu przypadkach plik tymczasowy nie powinien pozostać na dysku po zakończeniu działania programu.
Ps. Podczas testowania tego kodu w systemie Windows zauważyłem dość zaskakujący fakt: najwyraźniej samo pozostawienie niezamkniętego pliku tymczasowego wystarczy, aby zapobiec jego usunięciu . Oczywiście oznacza to również, że każda awaria, która zdarzy się, gdy plik tymczasowy jest używany, spowoduje, że pozostanie on nieusunięty, czego właśnie staramy się tutaj uniknąć .
AFAIK, jedynym sposobem uniknięcia tego jest upewnienie się, że plik tymczasowy jest zawsze zamykany za pomocą finally
bloku. Oczywiście równie dobrze możesz usunąć plik z tego samego finally
bloku. Nie jestem pewien, co, jeśli w ogóle cokolwiek, .deleteOnExit()
mogłoby cię przez to przekonać.