假设我使用 Java 方法创建一个临时文件
File tmp = File.createTempFile(prefix, suffix);
如果我不明确调用
delete()
方法,文件什么时候会被删除?
直觉上,它可能是在 JVM 终止时,或早些时候(由垃圾收集器),或稍后(由某些操作系统清理进程)。
File.createTempFile
:
此方法仅提供临时文件功能的一部分。要安排自动删除由此方法创建的文件,请使用
方法。deleteOnExit()
File.deleteOnExit()
:
请求在虚拟机终止时删除此抽象路径名表示的文件或目录。
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.
不关闭临时文件就足以防止其被删除。 当然,这也意味着在使用临时文件时发生的任何崩溃都会导致其未被删除,这正是我们在这里试图避免的情况。
AFAIK,避免这种情况的唯一方法是确保使用 finally
always。 当然,您也可以删除同一个 finally
块中的文件。 我不确定使用
.deleteOnExit()
实际上会给你带来什么(如果有的话)。
delete()
方法,文件什么时候会被删除?。
不会,至少 Java 不会。 如果您希望在 JVM 终止时删除文件,则需要调用tmp.deleteOnExit()
来自:
File temp = File.createTempFile("abc", ".tmp");
temp.deleteOnExit();
上面的示例将创建一个名为“abc.tmp”的临时文件,并在程序终止或退出时将其删除。
如果需要,您可以在终止进程之前手动删除该文件,但是当进程终止时,该文件也会被删除。