如何在Java中创建临时目录/文件夹?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (10)
  • 关注 (0)
  • 查看 (2063)

在Java应用程序中是否有标准和可靠的方法来创建临时目录?有Java问题数据库中的一个条目,在注释中有一些代码,但是我想知道是否有一个标准的解决方案可以在一个常见的库中找到(ApacheCommons等)?

提问于
用户回答回答于

如果您正在使用JDK 7,请使用新的档案。CreateTempDirectory类创建临时目录。

在JDK 7之前,应该这样做:

public static File createTempDirectory()
    throws IOException
{
    final File temp;

    temp = File.createTempFile("temp", Long.toString(System.nanoTime()));

    if(!(temp.delete()))
    {
        throw new IOException("Could not delete temp file: " + temp.getAbsolutePath());
    }

    if(!(temp.mkdir()))
    {
        throw new IOException("Could not create temp directory: " + temp.getAbsolutePath());
    }

    return (temp);
}

如果需要,可以创建更好的例子(子类IOException)。

用户回答回答于

你首先可调用tempDir.delete()。或者你可以用System.getProperty("java.io.tmpdir")在那里创建一个目录。不管怎样,你都应该记得调用tempDir.deleteOnExit(),否则文件在你完成后不会被删除。

用户回答回答于

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

用户回答回答于

这就是我决定为我自己的代码做的事情:

/**
 * Create a new temporary directory. Use something like
 * {@link #recursiveDelete(File)} to clean this directory up since it isn't
 * deleted automatically
 * @return  the new directory
 * @throws IOException if there is an error creating the temporary directory
 */
public static File createTempDir() throws IOException
{
    final File sysTempDir = new File(System.getProperty("java.io.tmpdir"));
    File newTempDir;
    final int maxAttempts = 9;
    int attemptCount = 0;
    do
    {
        attemptCount++;
        if(attemptCount > maxAttempts)
        {
            throw new IOException(
                    "The highly improbable has occurred! Failed to " +
                    "create a unique temporary directory after " +
                    maxAttempts + " attempts.");
        }
        String dirName = UUID.randomUUID().toString();
        newTempDir = new File(sysTempDir, dirName);
    } while(newTempDir.exists());

    if(newTempDir.mkdirs())
    {
        return newTempDir;
    }
    else
    {
        throw new IOException(
                "Failed to create temp dir named " +
                newTempDir.getAbsolutePath());
    }
}

/**
 * Recursively delete file or directory
 * @param fileOrDir
 *          the file or dir to delete
 * @return
 *          true iff all files are successfully deleted
 */
public static boolean recursiveDelete(File fileOrDir)
{
    if(fileOrDir.isDirectory())
    {
        // recursively delete contents
        for(File innerFile: fileOrDir.listFiles())
        {
            if(!FileUtilities.recursiveDelete(innerFile))
            {
                return false;
            }
        }
    }

    return fileOrDir.delete();
}
用户回答回答于

截至JAVA 1.7createTempDirectory(prefix, attrs)createTempDirectory(dir, prefix, attrs)包括在java.nio.file.Files

例子:File tempDir = Files.createTempDirectory("foobar").toFile();

用户回答回答于

不使用deleteOnExit()即使你以后显式删除它。

Google 'deleteonexit is evil' 有关更多信息,但问题的要点是:

  1. deleteOnExit()只删除正常JVM关闭,而不是崩溃或杀死JVM进程。
  2. deleteOnExit()只有在JVM关闭时删除--对于长期运行的服务器进程不好,
  3. 最坏的是-deleteOnExit()消耗每个临时文件条目的内存。如果您的进程运行了几个月,或者在短时间内创建了大量的临时文件,那么您将消耗内存,并且在JVM关闭之前永远不会释放它。
用户回答回答于

这是Guava库的Files.createTempDir()的源代码。它没有你想象的那么复杂:

public static File createTempDir() {
  File baseDir = new File(System.getProperty("java.io.tmpdir"));
  String baseName = System.currentTimeMillis() + "-";

  for (int counter = 0; counter < TEMP_DIR_ATTEMPTS; counter++) {
    File tempDir = new File(baseDir, baseName + counter);
    if (tempDir.mkdir()) {
      return tempDir;
    }
  }
  throw new IllegalStateException("Failed to create directory within "
      + TEMP_DIR_ATTEMPTS + " attempts (tried "
      + baseName + "0 to " + baseName + (TEMP_DIR_ATTEMPTS - 1) + ')');
}

默认情况下:

private static final int TEMP_DIR_ATTEMPTS = 10000;

看这里

用户回答回答于

为解决这个问题而编写的代码天真地受到了race条件的影响,包括这里的几个答案。历史上,你可以仔细考虑race状况,自己写,或者你可以使用第三方库,比如谷歌的Guava库,或者你可以编写buggy 代码。

但是从JDK 7开始,Java标准库本身现在为这个问题提供了一个正常工作的(不活跃的)解决方案。你想从文件中获取java.nio.file.Files#createTempDirectory()

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

在指定目录中创建一个新目录,使用给定的前缀生成其名称。生成的路径与给定目录的文件系统相关联。 关于如何构造目录名称的详细信息是依赖于实现的,因此没有指定。在可能的情况下,前缀用于构造候选名称。

用户回答回答于

如果您需要一个临时目录进行测试,并且您使用的是jUnit,@Rule连同TemporaryFolder解决你的问题:

@Rule
public TemporaryFolder folder = new TemporaryFolder();

从文件中:

TemporaryFold规则允许创建保证在测试方法完成时被删除的文件和文件夹(无论它是通过还是失败)

参考文献:http://jun it.org/apidocs/org/junit/Rules/TemporaryFolder.html

用户回答回答于

谷歌Guava library 有大量有用的实用工具。这里值得注意的是文件类.它有许多有用的方法,包括:

File myTempDir = Files.createTempDir();

这完全符合你的要求。如果您阅读了这里的文档,您将看到建议的文件改编。createTempFile(“install”、“dir”)通常会引入安全漏洞。

扫码关注云+社区

领取腾讯云代金券