是否有一种在Java应用程序中创建临时目录的标准而可靠的方法?在Java的问题数据库中有一个条目,在评论中有一些代码,但我想知道在一个常用的库(Apache Commons等)中是否有一个标准的解决方案?


当前回答

createTempFile实际上创建了文件。那么为什么不先删除它,然后再对它执行mkdir呢?

其他回答

这段代码应该可以很好地工作:

public static File createTempDir() {
    final String baseTempPath = System.getProperty("java.io.tmpdir");

    Random rand = new Random();
    int randomInt = 1 + rand.nextInt();

    File tempDir = new File(baseTempPath + File.separator + "tempDir" + randomInt);
    if (tempDir.exists() == false) {
        tempDir.mkdir();
    }

    tempDir.deleteOnExit();

    return tempDir;
}

谷歌Guava库有大量有用的实用程序。这里需要注意的是Files类。它有很多有用的方法,包括:

File myTempDir = Files.createTempDir();

这正是您在一行中要求的。如果您阅读这里的文档,您将看到File的建议改编。createTempFile("install", "dir")通常会引入安全漏洞。

为解决这个问题而编写的天真代码会受到竞争条件的影响,包括这里的几个答案。从历史上看,您可以仔细考虑竞争条件并自己编写它,或者您可以使用第三方库,如谷歌的Guava(正如Spina的回答所建议的那样)。或者你可以编写有bug的代码。

但是对于JDK 7,有一个好消息!Java标准库本身现在为这个问题提供了一个正常工作的(非刺激性的)解决方案。你需要java.nio.file.Files#createTempDirectory()。从文档中可以看到:

public static Path createTempDirectory(Path dir,
                       String prefix,
                       FileAttribute<?>... attrs)
                                throws IOException

在指定目录中创建一个新目录,使用给定的前缀生成其名称。生成的Path与给定目录的相同文件系统相关联。

关于如何构造目录名称的详细信息取决于实现,因此没有指定。在可能的情况下,前缀用于构造候选名称。

这有效地解决了Sun bug跟踪器中要求这样一个功能的令人尴尬的古老bug报告。

即使稍后显式删除它,也不要使用deleteOnExit()。

谷歌'deleteonexit is evil'获取更多信息,但问题的要点是:

deleteOnExit()只删除正常的JVM关闭,不删除崩溃或杀死JVM进程。 deleteOnExit()只在JVM关闭时删除-不适合长时间运行的服务器进程,因为: 最糟糕的是deleteOnExit()为每个临时文件条目消耗内存。如果您的进程运行了几个月,或者在短时间内创建了大量临时文件,那么您将消耗内存,直到JVM关闭才释放内存。

createTempFile实际上创建了文件。那么为什么不先删除它,然后再对它执行mkdir呢?