根据我的理解,使用Files.walkFileTree遍历文件树时处理异常的常用方法是在访问者实现中实现一些try / catch逻辑,例如通过静默忽略任何AccessDeniedExceptions并转移到其他文件。但是我想我发现了一个调用来自访问者代码之外的异常的情况,这使得很难对它做任何事情。结果是整个文件遍历崩溃。是的,它是在遍历linux上的特殊/ proc文件系统时发生的。
在同一路径上使用旧的Java API File.list(..)不会崩溃,它只是静默地返回一个空列表。
我的问题是,有没有办法确保像这样的权限问题不会中断整个文件遍历?
对于此特定目录,我的用户似乎是文件夹及其所有内容的所有者,如下所示:
thomas.larsson@anonymized $ sudo ls -la /proc/2662/map_files
total 0
dr-x------ 2 thomas.larsson thomas 0 mar 4 09:44 .
dr-xr-xr-x 9 thomas.larsson thomas 0 mar 4 09:11 ..
lr-------- 1 thomas.larsson thomas 64 mar 4 12:39 7f67499df000-7f67499ea000 -> /lib/x86_64-linux-gnu/libnss_files-2.19.so
...
这让我觉得我无法在preVisitDirectory方法中做任何事情,比如检查PosixFileAttributes以确定我是否可以读取这个目录。
这是一个junit片段,可以为我重现问题
package com.apa;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
public class Example {
@Test
public void testWalk() throws IOException {
Files.walkFileTree(Paths.get("/proc/2662/map_files"), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
System.out.println("Visiting " + file);
return super.visitFile(file, attrs);
}
});
}
@Test
public void oldApi() {
String[] list = new File("/proc/2662/map_files").list();
}
}
相应的堆栈跟踪是:
java.nio.file.FileSystemException: /proc/2662/map_files: Operation not permitted
at sun.nio.fs.UnixException.translateToIOException(UnixException.java:91)
at sun.nio.fs.UnixException.asIOException(UnixException.java:111)
at sun.nio.fs.UnixDirectoryStream$UnixDirectoryIterator.readNextEntry(UnixDirectoryStream.java:171)
at sun.nio.fs.UnixDirectoryStream$UnixDirectoryIterator.hasNext(UnixDirectoryStream.java:201)
at java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:198)
at java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:69)
at java.nio.file.Files.walkFileTree(Files.java:2600)
at java.nio.file.Files.walkFileTree(Files.java:2633)
at com.klarna.filewatch.Example.walkTheWalk(Example.java:14)
...
最诚挚的问候 /托马斯
答案 0 :(得分:0)
根据https://docs.oracle.com/javase/7/docs/api/java/nio/file/SimpleFileVisitor.html,visitFileFailed方法的默认行为是重新抛出异常。
您可能希望覆盖该方法以自行处理异常。