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

问题描述 投票:36回答:5

目前我正在试图递归删除目录...很奇怪的代码最短的那一块我能找到的是下面的结构,使用一个特设的内部类和一个访问者模式...

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();
}

来源:here

这感觉可怕的笨拙又麻烦,因为新的API nio删除这么多的混乱和样板......

有没有达到强制,递归目录删除的任何短呢?

我在寻找纯粹的原生Java 1.8的方法,所以请不要链接到外部库...

java directory nio delete-file
5个回答
105
投票

您可以结合NIO 2和流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
Files.walk(rootPath)
    .sorted(Comparator.reverseOrder())
    .map(Path::toFile)
    .peek(System.out::println)
    .forEach(File::delete);
  • Files.walk - 返回下面rootPath所有文件/目录包括
  • .sorted - 按照相反的顺序列表,因此该目录本身自带的,包括子目录和文件后,
  • qazxsw POI - 映射qazxsw POI到qazxsw POI
  • .map - 在那里只显示哪个条目被处理
  • Path - 把任何File对象的.peek方法

编辑

这里有一些数字。 该目录包含.forEach的jdk1.8.0_73解压.delete()而最近File的构建。

/data/to-delete

以毫秒为单位时报

rt.jar

这两个版本不打印文件名被处决。最限制因素是驱动器。不是实现。

编辑

有关选项qazxsw POI一些额外的信息。

假设下面的文件和目录结构

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 不会被删除的文件。

注意:不要使用代码复制和粘贴不理解它做什么。


5
投票

下面的解决方案并不需要转换从文件路径的对象:

Files.walk(rootPath, FileVisitOption.FOLLOW_LINKS)

4
投票

如果您只能使用Java 7中与NIO

/tmp/dont_delete/bar

3
投票

如果你已经有弹簧芯作为项目的一部分,这里是一个简单的方法来做到这一点:

Files.walk(rootPath)

来源:/tmp/dont_delete/bar


1
投票
Path rootPath = Paths.get("/data/to-delete");     
final List<Path> pathsToDelete = Files.walk(rootPath).sorted(Comparator.reverseOrder()).collect(Collectors.toList());
for(Path path : pathsToDelete) {
    Files.deleteIfExists(path);
}

你需要的“尝试与资源”模式,如果“文件系统资源的及时处置,需要”关闭流。

此外,可能是一个不受欢迎的评论,但它是更清洁,更具可读性使用图书馆。随着共享功能的代码,它不会占用太多空间。每个人谁看你的代码必须验证这个代码适当删除,它绝不是显而易见的。


0
投票

Path path = Paths.get("./target/logs"); Files.walkFileTree(path, new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Files.delete(file); return FileVisitResult.CONTINUE; } @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { Files.delete(dir); return FileVisitResult.CONTINUE; } }); FileSystemUtils.deleteRecursively(file); 递归删除目录。

例:

http://www.baeldung.com/java-delete-directory

欲了解更多信息,请参阅Files.walk(pathToBeDeleted).sorted(Comparator.reverseOrder()).forEach(Files::delete);

© www.soinside.com 2019 - 2024. All rights reserved.