Java临时文件何时被删除?

假设我用这个方法在Java中创build一个临时文件

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

如果我不明确地调用delete()方法,文件何时被删除?

直观地说,可能是JVM终止,或者更早 (垃圾收集器),或者更 (通过一些操作系统清除过程)。

该文件不会自动从JavaDoc中删除:

此方法仅提供临时文件设施的一部分。 要安排由该方法创build的文件被自动删除,请使用deleteOnExit()方法。

所以你必须明确地调用deleteOnExit() :

请求在该虚拟机终止时删除由该抽象path名表示的文件或目录。

正如其他答案所指出的,使用File.createTempFile()创build的临时文件不会自动删除,除非您明确地请求它。

通用的可移植方法是在File对象上调用.deleteOnExit() ,当JVM终止时它将调度文件以进行删除。 然而,这种方法的一个小缺点是只有在VM正常终止的情况下才有效。 在exception终止(即虚拟机崩溃或强制终止虚拟机进程)时,该文件可能会保持未删除状态。

在UNIX系统(如Linux)上,实际上可以通过在打开临时文件后立即删除临时文件来获得更可靠的解决scheme。 这是有效的,因为Unix文件系统允许一个文件在被一个或多个进程保持打开的状态下被删除(不连接 ,准确地说)。 这些文件可以通过打开的文件句柄正常访问,并且在最后一个进程持有文件的打开句柄退出之后,它们只占用磁盘空间。

所以这里是我所知道的最可靠和便携的方式,以确保在程序退出后临时文件将被正确删除:

 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. 

不pipe怎样,在程序结束之后,临时文件不应该保留在磁盘上。


PS。 在Windows上testing这个代码的时候,我观察到了一个相当令人惊讶的事实:显然,仅仅让temp文件closures就足以使它不被删除 。 当然,这也意味着在临时文件被使用时发生的任何崩溃都将导致它被取消删除,这正是我们在这里要避免的

AFAIK,避免这种情况的唯一方法是确保临时文件总是使用finally块closures。 当然,那么你也可以在finally块中删除文件。 我不确定使用.deleteOnExit()什么,如果有的话,实际上会让你获益。

如果我不明确地调用delete()方法,文件何时被删除?

它不会,至less不会被Java。 如果您希望在JVM终止时删除文件,则需要调用tmp.deleteOnExit()

从: 如何删除Java中的临时文件

临时文件用于存储不太重要的临时数据, 当系统终止时应始终删除临时数据。 最好的做法是使用File.deleteOnExit()来做到这一点。

例如,

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

上面的例子将创build一个名为“abc.tmp”的临时文件,并在程序终止或退出时将其删除

如果要手动删除临时文件 ,则仍然可以使用File.delete()。

临时文件用于存储不太重要的临时数据,当系统终止时应始终删除临时数据。 最好的做法是使用File.deleteOnExit()来做到这一点。

例如,

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

上面的例子将创build一个名为“abc.tmp”的临时文件,并在程序终止或退出时将其删除。

如果需要,可以在终止进程之前手动删除文件,但是当进程终止时,该文件也将被删除。