Files.createTempDirectory
方法会在JVM正常退出后自动删除临时目录吗?还是我需要手动递归删除临时目录内容?
Files.createTempDirectory
方法会在JVM正常退出后自动删除临时目录吗?还是我需要手动递归删除临时目录内容?
Files.createTempDirectory()
创建的临时目录在系统退出(JVM终止)时不会被删除,除非您配置它们这样做:
可以使用关闭挂钩或
File.deleteOnExit()
机制自动删除目录。
意思是您可以调用:
Path tmp = Files.createTempDirectory(null);
tmp.toFile().deleteOnExit();
然而,只有当目录为空时才能删除它,如File.delete()
所示:
删除由此抽象路径名表示的文件或目录。如果此路径名表示目录,则必须先清空该目录才能删除。
因此,如果要删除目录及其内容,我们需要更高级的方法。您可以像这样递归地注册目录及其子目录以进行删除:
public static void recursiveDeleteOnExit(Path path) throws IOException {
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file,
@SuppressWarnings("unused") BasicFileAttributes attrs) {
file.toFile().deleteOnExit();
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult preVisitDirectory(Path dir,
@SuppressWarnings("unused") BasicFileAttributes attrs) {
dir.toFile().deleteOnExit();
return FileVisitResult.CONTINUE;
}
});
}
注意,这将注册所有当前存在的文件以便删除 - 如果在调用此方法后创建了新文件,则根据File.delete()
文档中记录的行为,它们及其父目录将不会被删除。
如果你想要在退出时删除目录,无论该目录的内容如何,你可以使用一个关机挂钩(shutdown-hook),使用几乎相同的方式:
public static void recursiveDeleteOnShutdownHook(final Path path) {
Runtime.getRuntime().addShutdownHook(new Thread(
new Runnable() {
@Override
public void run() {
try {
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file,
@SuppressWarnings("unused") BasicFileAttributes attrs)
throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException e)
throws IOException {
if (e == null) {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
// directory iteration failed
throw e;
}
});
} catch (IOException e) {
throw new RuntimeException("Failed to delete "+path, e);
}
}}));
}
请注意,反复调用此方法会每次注册一个新的关闭线程,这可能在大规模操作时造成问题。File.deleteOnExit()
会存储一组已注册的文件,并在一个关闭钩子中删除所有这些文件。如果您需要以类似的方式删除多个目录,则应实现类似的机制。
file.deleteOnExit()
方法手动删除目录。prefix
参数可以为空。 - user972946null
?你当然可以调用Files.createTempDirectory(null)
,这正如人们所期望的那样工作 - 它创建一个新的任意命名的目录并返回其路径。 - dimo414Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
try {
FileUtils.deleteDirectory(tmp_dir_path.toFile());
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
有关Apache Commons的更多信息,请查看:https://commons.apache.org/proper/commons-io/
createTempDirectory
与createTempFile
方法一样,此方法仅是临时文件设施的一部分。可以使用shutdown-hook或File.deleteOnExit()
机制自动删除目录。java.io.File.deleteOnExit()
,但我猜它对非空目录无效。new File(Files.createTempDirectory(null).toString()).deleteOnExit()
可以工作的话,我会更喜欢Java,哈哈哈。 - user972946@TempDir
注释非常好用。它还会在测试或测试类结束时(取决于注释的作用域)递归删除创建的目录。@BeforeAll
public static void setup(@TempDir Path tempDir) {
// The dir will be deleted when the class ends, ala @AfterClass
}
或者
@Test
public static void myTest(@TempDir Path tempDir) {
// The dir will be deleted when this test method ends
}
org.springframework.util.FileSystemUtils.deleteRecursively(File root)
,用于显式递归删除目录。 - Sergey Shcherbakov