是否有一种在Java应用程序中创建临时目录的标准而可靠的方法?在Java的问题数据库中有一个条目,在评论中有一些代码,但我想知道在一个常用的库(Apache Commons等)中是否有一个标准的解决方案?
当前回答
使用file# createTempFile和delete为目录创建一个唯一的名称似乎是可以的。您应该添加一个ShutdownHook,以便在JVM关闭时(递归地)删除目录。
其他回答
如果你需要一个临时目录进行测试,并且你正在使用jUnit, @Rule和TemporaryFolder可以解决你的问题:
@Rule
public TemporaryFolder folder = new TemporaryFolder();
从文档中可以看到:
TemporaryFolder规则允许创建文件和文件夹,这些文件和文件夹保证在测试方法完成时被删除(无论它通过还是失败)。
更新:
如果您正在使用JUnit Jupiter(版本5.1.1或更高),您可以选择使用JUnit Pioneer,它是JUnit 5扩展包。
摘自项目文档:
例如,下面的测试为单个测试方法注册扩展名,创建一个文件并将其写入临时目录,并检查其内容。
@Test
@ExtendWith(TempDirectory.class)
void test(@TempDir Path tempDir) {
Path file = tempDir.resolve("test.txt");
writeFile(file);
assertExpectedFileContent(file);
}
更多信息在JavaDoc和TempDirectory的JavaDoc中
Gradle:
dependencies {
testImplementation 'org.junit-pioneer:junit-pioneer:0.1.2'
}
Maven:
<dependency>
<groupId>org.junit-pioneer</groupId>
<artifactId>junit-pioneer</artifactId>
<version>0.1.2</version>
<scope>test</scope>
</dependency>
更新2:
@TempDir注释作为实验特性被添加到JUnit Jupiter 5.4.0发行版中。示例摘自JUnit 5用户指南:
@Test
void writeItemsToFile(@TempDir Path tempDir) throws IOException {
Path file = tempDir.resolve("test.txt");
new ListWriter(file).write("a", "b", "c");
assertEquals(singletonList("a,b,c"), Files.readAllLines(file));
}
即使稍后显式删除它,也不要使用deleteOnExit()。
谷歌'deleteonexit is evil'获取更多信息,但问题的要点是:
deleteOnExit()只删除正常的JVM关闭,不删除崩溃或杀死JVM进程。 deleteOnExit()只在JVM关闭时删除-不适合长时间运行的服务器进程,因为: 最糟糕的是deleteOnExit()为每个临时文件条目消耗内存。如果您的进程运行了几个月,或者在短时间内创建了大量临时文件,那么您将消耗内存,直到JVM关闭才释放内存。
从Java 1.7开始,createTempDirectory(prefix, attrs)和createTempDirectory(dir, prefix, attrs)包含在Java .nio.file. files中
操作: 寺庙文件。
我喜欢创建唯一名称的多次尝试,但即使是这种解决方案也不排除竞争条件。另一个进程可以在exists()和if(newTempDir.mkdirs())方法调用测试之后插入。我不知道如何在不求助于本机代码的情况下完全使其安全,我认为这是隐藏在File.createTempFile()中的内容。
这段代码应该可以很好地工作:
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;
}
推荐文章
- Java中的split()方法对点(.)不起作用。
- Eclipse调试器总是阻塞在ThreadPoolExecutor上,没有任何明显的异常,为什么?
- Java生成两个给定值之间的随机数
- 如何有效地从数组列表或字符串数组中删除所有空元素?
- 比较JUnit断言中的数组,简洁的内置方式?
- codestyle;把javadoc放在注释之前还是之后?
- 如何在Spring中定义List bean ?
- 将Set<T>转换为List<T>的最简洁的方法
- 在JavaScript中,什么相当于Java的Thread.sleep() ?
- 使用Java重命名文件
- URL从Java中的类路径加载资源
- .toArray(new MyClass[0]) or .toArray(new MyClass[myList.size()])?
- Hibernate中不同的保存方法之间有什么区别?
- Java 8流和数组操作
- Java Regex捕获组