问题描述
我目前正在尝试以递归方式删除目录...奇怪的是,我能够找到的最短代码是以下构造,使用 ad-hoc内部类并在访客模式 ...
I am currently trying to recursively delete a directory... Strangely enough the shortest piece of code I was able to find is the following construct, employing an ad-hoc inner class and in a visitor pattern...
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();
}
资料来源:
这感觉非常笨拙和冗长,鉴于新的 nio
API消除了这么多的混乱和样板......
This feels horribly clumsy and verbose, given that the new nio
APIs remove so much clutter and boilerplate...
有没有更短的方式实现强制递归目录删除?
我正在寻找纯本机Java 1.8方法,所以请不要链接到外部库...
I'm looking for pure native Java 1.8 methods, so please don't link to external libraries...
推荐答案
您可以将NIO 2和Stream API结合使用。
You can combine NIO 2 and the 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
Files.walk(rootPath)
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.peek(System.out::println)
.forEach(File::delete);
-
Files.walk
- 返回rootPath
以下的所有文件/目录,包括 -
.sorted
- 以相反的顺序对列表进行排序,因此目录本身位于包含子目录和文件之后 -
.map
- 映射路径
到文件
-
.peek
- 是否只显示处理了哪个条目 -
.forEach
- 调用.delete ()
每个文件的方法
对象 Files.walk
- return all files/directories belowrootPath
including.sorted
- sort the list in reverse order, so the directory itself comes after the including subdirectories and files.map
- map thePath
toFile
.peek
- is there only to show which entry is processed.forEach
- calls the.delete()
method on everyFile
object
编辑
以下是一些数字。
目录 / data / to-delete
包含jdk1.8.0_73的解压缩 rt.jar
以及。
Here are some figures.
The directory /data/to-delete
contained the unpacked rt.jar
of jdk1.8.0_73 and a recent build of 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
两个版本均为执行时不打印文件名。最受限制因素是驱动器。不是实施。
Both version were executed without printing file names. The most limiting factor is the drive. Not the implementation.
编辑
关于选项<$的一些附加信息C $ C> FileVisitOption.FOLLOW_LINKS 。
假设以下文件和目录结构
Assume following file and directory structure
/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
也将被删除。
will follow symlinks and the file /tmp/dont_delete/bar
would be deleted as well.
使用
Files.walk(rootPath)
不会跟随符号链接,文件 / tmp / dont_delete / bar
也不会被删除。
will not follow symlinks and the file /tmp/dont_delete/bar
would not be deleted.
注意:切勿在不了解代码的情况下使用代码进行复制和粘贴。
NOTE: Never use code as copy and paste without understanding what it does.
这篇关于Java.nio:最简洁的递归目录删除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!