Java临时文件什么时候删除?

问题描述 投票:0回答:6

假设我使用 Java 方法创建一个临时文件

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

如果我不明确调用

delete()
方法,文件什么时候会被删除?

直觉上,它可能是在 JVM 终止时,或早些时候(由垃圾收集器),或稍后(由某些操作系统清理进程)。

java garbage-collection temporary-files
6个回答
119
投票

文件不会自动删除。参见

File.createTempFile

此方法仅提供临时文件功能的一部分。要安排自动删除由此方法创建的文件,请使用

deleteOnExit()
方法。

所以你必须显式调用

File.deleteOnExit()
:

请求在虚拟机终止时删除此抽象路径名表示的文件或目录。


64
投票

正如其他答案所指出的,除非您明确请求,否则使用

File.createTempFile()
创建的临时文件将不会被自动删除。

执行此操作的通用、可移植方法是在 .deleteOnExit()

 对象上调用 
File
,这将安排在 JVM 终止时删除文件。  然而,这种方法的一个小缺点是它只有在虚拟机正常终止时才有效。如果出现异常终止(即虚拟机崩溃或强制终止虚拟机进程),该文件可能不会被删除。

在 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 { // 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.

但是,无论哪种情况,程序结束后临时文件都不应保留在磁盘上。

Ps.
在 Windows 上测试此代码时,我观察到一个相当令人惊讶的事实:显然,仅

不关闭临时文件就足以防止其被删除。 当然,这也意味着在使用临时文件时发生的任何崩溃都会导致其未被删除,这正是我们在这里试图避免的情况。 AFAIK,避免这种情况的唯一方法是确保使用 finally

块关闭临时文件

always。 当然,您也可以删除同一个 finally

 块中的文件。  我不确定使用 
.deleteOnExit()
 实际上会给你带来什么(如果有的话)。


18
投票
delete()
方法,文件什么时候会被删除?


不会,至少 Java 不会。 如果您希望在 JVM 终止时删除文件,则需要调用

tmp.deleteOnExit()


来自:

8
投票

临时文件用于存储不太重要的临时数据,

当您的系统终止时,应始终将其删除
。这 最佳实践是使用 File.deleteOnExit() 来执行此操作。

例如,

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

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

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

临时文件用于存储不太重要的临时数据,当系统终止时应始终删除这些数据。最佳实践是使用 File.deleteOnExit() 来执行此操作。


4
投票

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

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


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


-3
投票

© www.soinside.com 2019 - 2024. All rights reserved.