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

时间:2013-05-22 12:12:45

标签: java garbage-collection temporary-files

假设我使用方法

在Java中创建临时文件
File tmp = File.createTempFile(prefix, suffix);

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

直观地说,可能是JVM终止时,或早期(垃圾收集器)或以后(通过某些操作系统清扫过程)。 / p>

6 个答案:

答案 0 :(得分:75)

不会从JavaDoc

自动删除该文件
  

此方法仅提供临时文件工具的一部分。至   安排通过此方法创建的文件自动删除,   使用deleteOnExit()方法。

所以你必须明确地呼叫deleteOnExit()

  

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

答案 1 :(得分:48)

正如其他答案所述,除非您明确要求,否则使用File.createTempFile()创建的临时文件将自动删除

执行此操作的通用,可移植方法是在File对象上调用.deleteOnExit(),该对象将在JVM终止时调度文件以进行删除。然而,这种方法的一个小缺点是它只能在VM正常终止时起作用;如果异常终止(即VM崩溃或VM进程被强制终止),该文件可能会被取消删除。

在Unixish系统(例如Linux)上,通过在打开后立即删除临时文件 ,实际上可以获得更可靠的解决方案。这是有效的,因为Unix文件系统允许删除文件(准确地说是unlinked),而它仍然由一个或多个进程保持打开状态。这些文件可以通过打开的文件句柄正常访问,它们在磁盘上占用的空间只有在最后一个持有文件打开句柄的进程退出后才会被操作系统回收。

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

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块关闭临时文件总是。当然,您也可以删除同一finally块中的文件。我不确定使用.deleteOnExit()使用{{1}}会有什么好处。

答案 2 :(得分:17)

  

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

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

答案 3 :(得分:4)

来自:How to delete temporary file in Java

  

临时文件用于存储不太重要和临时的数据,   系统终止时应始终删除 。该   最佳实践是使用File.deleteOnExit()来完成它。

例如,

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

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

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

答案 4 :(得分:3)

临时文件用于存储不太重要和临时的数据,在系统终止时应始终删除这些数据。最佳做法是使用File.deleteOnExit()来完成它。

例如,

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

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

答案 5 :(得分:0)

如果您愿意,可以在终止流程之前手动删除文件,但是当流程终止时,文件也会被删除。