文章首发于:clawhub.club
walkFileTree
NIO用来操作文件的API用起来是很舒服的,特别是这个walkFileTree静态方法:
1 2 3 4
| public static Path walkFileTree(Path start, Set<FileVisitOption> options, int maxDepth, FileVisitor<? super Path> visitor)
|
- start
开始的文件,也就是你要操作的文件夹
- options
配置遍历的选项,一般用EnumSet.of(FileVisitOption.FOLLOW_LINKS)遵循符号链接填充。
- maxDepth
迭代的最大深度
- visitor
要为每个文件调用的文件访问器,一般使用SimpleFileVisitor,因为可以任意实现自己想要使用的方法,其实现了FileVisitor接口。
这个方法的设计就是回调思想。
FileVisitor
FileVisitor接口中有四个方法:
preVisitDirectory
在访问目录中的项之前为目录调用。
visitFile
为目录中的文件调用。
visitFileFailed
为无法访问的文件调用。如果无法读取文件的属性、文件是无法打开的目录以及其他原因,则调用此方法。
postVisitDirectory
在访问了目录中的项及其所有子项之后,为目录调用。当目录的迭代提前完成时或者在遍历目录时调用I/O错误也会调用此方法。
FileVisitResult
此枚举类有四个选项:
- CONTINUE:继续遍历
- SKIP_SIBLINGS:继续遍历,但忽略当前节点的所有兄弟节点直接返回上一层继续遍历
- SKIP_SUBTREE:继续遍历,但是忽略子目录,但是子文件还是会访问;
- TERMINATE:终止遍历
应用
批量删除文件夹及其子文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
public static void deleteAllFileAndFolders(Path folder) throws IOException { Files.walkFileTree(folder, 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 e) throws IOException { if (e == null) { Files.deleteIfExists(dir); return FileVisitResult.CONTINUE; } else { throw e; } } }); }
|
统计文件夹下所有文件数量
迭代深度可以自由控制。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
public static Set<Path> findFolders(String folder) throws IOException { Set<Path> folders = new HashSet<>(); Path path = Paths.get(folder); Files.walkFileTree(path, EnumSet.of(FileVisitOption.FOLLOW_LINKS), 2, new SimpleFileVisitor<Path>() { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { folders.add(dir);
return FileVisitResult.CONTINUE; } }); folders.remove(path); return folders; }
|