当前位置: 首页 > 面试题库 >

Java.nio:最简洁的递归目录删除

许明朗
2023-03-14
问题内容

我目前正在尝试递归删除目录…奇怪的是,我能够找到的最短代码是以下结构,采用了一个 临时内部类 并且采用了 访问者模式

Path rootPath = Paths.get("data/to-delete");

try {
  Files.walkFileTree(rootPath, new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
      System.out.println("delete file: " + file.toString());
      Files.delete(file);
      return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
      Files.delete(dir);
      System.out.println("delete dir: " + dir.toString());
      return FileVisitResult.CONTINUE;
    }
  });
} catch(IOException e){
  e.printStackTrace();
}

资料来源:这里

鉴于新的nioAPI消除了太多的混乱和样板,这让人感到非常笨拙和冗长。

有没有更短的方法可以实现强制递归目录删除?

我正在寻找纯本地Java 1.8方法,所以请不要链接到外部库…


问题答案:

您可以结合使用NIO 2和Stream API。

Path rootPath = Paths.get("/data/to-delete");
// before you copy and paste the snippet
// - read the post till the end
// - read the javadoc to understand what the code will do 
//
// a) to follow softlinks (removes the linked file too) use
// Files.walk(rootPath, FileVisitOption.FOLLOW_LINKS)
//
// b) to not follow softlinks (removes only the softlink) use
// the snippet below
try (Stream<Path> walk = Files.walk(rootPath)) {
    walk.sorted(Comparator.reverseOrder())
        .map(Path::toFile)
        .peek(System.out::println)
        .forEach(File::delete);
}
  • Files.walk-返回以下所有文件/目录,rootPath包括
  • .sorted -以相反的顺序对列表进行排序,因此目录本身位于包含子目录和文件的后面
  • .map-映射PathFile
  • .peek -仅显示要处理的条目
  • .forEach- .delete()在每个File对象上调用方法

编辑 正如@Seby首先提到的,现在由@JohnDough引用的,Files.walk()应该在try-with-resource构造中使用。多亏了两者。

从Files.walk javadoc

如果需要及时处理文件系统资源,则应使用try-with-resources构造来确保流操作完成后调用流的close方法。

编辑

这是一些数字。 该目录/data/to-delete包含解压缩rt.jar的jdk1.8.0_73和最新版本的activemq。

files: 36,427
dirs :  4,143
size : 514 MB

时间(以毫秒为单位)

                    int. SSD     ext. USB3
NIO + Stream API    1,126        11,943
FileVisitor         1,362        13,561

两种版本均执行时未打印文件名。最大的限制因素是驱动器。没有执行。

编辑

有关选项的一些其他信息FileVisitOption.FOLLOW_LINKS

假设以下文件和目录结构

/data/dont-delete/bar
/data/to-delete/foo
/data/to-delete/dont-delete -> ../dont-delete

使用

Files.walk(rootPath, FileVisitOption.FOLLOW_LINKS)

将遵循符号链接,该文件/tmp/dont_delete/bar也将被删除。

使用

Files.walk(rootPath)

将不会遵循符号链接,并且/tmp/dont_delete/bar不会删除该文件。

注意: 切勿在不了解代码功能的情况下将代码用作复制和粘贴。



 类似资料:
  • 问题内容: 有没有办法用Java递归删除整个目录? 在正常情况下,可以删除一个空目录。但是,要删除带有目录的整个目录,就不再那么简单了。 如何用Java删除包含目录的整个目录? 问题答案: 你应该查看。它有一个类,可以执行你想要的操作。

  • 本文向大家介绍C++递归删除一个目录实例,包括了C++递归删除一个目录实例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C++递归删除一个目录的实现方法。分享给大家供大家参考。具体方法如下: CFindFile的使用框架如下: 递归删除代码如下: 希望本文所述对大家的C++程序设计有所帮助。

  • 本文向大家介绍php递归删除目录与文件的方法,包括了php递归删除目录与文件的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了php递归删除目录与文件的方法。分享给大家供大家参考。具体实现方法如下: 希望本文所述对大家的PHP程序设计有所帮助。

  • 问题内容: 我使用Gson 库将Java对象转换为Json响应…问题是,在JPA请求之后,由于与其他实体的递归关系,无法转换从DB检索到的对象: 我的源代码: 如您在这里看到的,我做了: 只是通过为coordonneesList中的每个GPS对象设置null来消除递归关系。 您认为这是一个很好的解决方案,或者还有其他更实用的方法吗?谢谢 问题答案: 有一个名为GraphAdapterBuilder

  • 我们在“线性回归的简洁实现”一节中已经了解了使用Gluon实现模型的便利。下面,让我们再次使用Gluon来实现一个softmax回归模型。首先导入所需的包或模块。 %matplotlib inline import d2lzh as d2l from mxnet import gluon, init from mxnet.gluon import loss as gloss, nn 获取和读

  • 问题内容: 我正在编写一个Python备份脚本,需要在目录(及其子目录)中找到最旧的文件。我还需要仅将其过滤为* .avi文件。 该脚本将始终在Linux计算机上运行。有什么方法可以在Python中完成,还是运行一些Shell命令会更好? 目前,我正在努力获取特定分区上的可用空间,如果可用空间不足5 GB,我想开始删除最旧的文件,直到满足该条件为止。 问题答案: 嗯 Nadia的答案是接近你什么