java.nio.file.Files
Stream<Path> Files.walk(Path start, FileVistOption... options)
返回一个以start为根的Path流,只有对该流执行最终(terminate)操作时,才会生成对应的流对象,如执行foreach操作就会触发流的生成。
该方法与Files.walk(start, Integer.MAX_VALUE, options) 等价,会访问以start为根的文件树下的所有文件(夹)。
在访问该方法返回的Path流的过程中,如果有一个文件(夹)没有访问权限,会抛出java.nio.file.AccessDeniedException异常,导致流终止,从而无法访问后续的文件。访问文件树的过程中,如果可能出现异常,建议使用Files.walkFileTree
Path walkFileTree(Path start, FileVisitor<? super Path> visitor)
该方法和 walkFileTree(start, EnumSet.noneOf(FileVisitOption.class), Integer.MAX_VALUE, visitor)等价。会访问以start为根的文件树下的所有文件。
该方法比Files.walk方法更可控,可以在FileVisitor中定义:文件访问失败的处理方式、如何访问文件、访问前&后的操作,代码如下:
Files.walkFileTree(Paths.get(dir), new SimpleFileVisitor<Path>(){
// 定义文件访问方式
@Override
public FileVisitResult visitFile(Path f, BasicFileAttributes attrs) {
// do sth
return FileVisitResult.CONTINUE;
}
// 定义访问失败时的处理方式
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
// 跳过文件子树,请根据自己的业务需要选择
return FileVisitResult.SKIP_SUBTREE;
}
// 定义文件访问前的操作
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
return super.preVisitDirectory(dir, attrs);
}
// 定义文件访问后的操作
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
return super.postVisitDirectory(dir, exc);
}
});
通过定义 FileVistor.visitFileFailed 方法返回 FileVistResult.SKIP_SUBTREE,当访问某个文件(夹)失败时,跳过该文件(夹)及其子树,继续访问后续的文件,从而解决Files.walk中某个文件访问失败导致后续文件无法访问的问题。