16

以下是一些简单的代码,仅用于测试该Files.walkFileTree()方法。但是,/etc/ssl/private具有这些权限 ( rwx--x---) 的文件夹会引发异常,即使我认为我使用 if 语句 ( if (permissions.equals("rwx--x---")) 保护它也是如此。

我究竟做错了什么?提前致谢。

public static void main (String []args) throws IOException, InterruptedException
{       
    Files.walkFileTree(Paths.get("/"), new WalkingTheThing2());
}

@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException
{
    PosixFileAttributeView posixView = Files.getFileAttributeView(dir, PosixFileAttributeView.class);
    PosixFileAttributes posixAttr = posixView.readAttributes();
    String permissions =PosixFilePermissions.toString(posixAttr.permissions());
    if (permissions.equals("rwx--x---"))
    {
        return FileVisitResult.SKIP_SUBTREE;
    }

    return FileVisitResult.CONTINUE;
}

@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
        throws IOException {
    try{

        System.out.println(file.getFileName()+" " +Files.size(file));

        return FileVisitResult.CONTINUE;
    }
    catch(IOException io){return FileVisitResult.CONTINUE;}
}

我得到的例外是: java.nio.file.AccessDeniedException: /etc/ssl/private

编辑:通过覆盖解决visitFileFailed

public FileVisitResult visitFileFailed(Path file, IOException io)
{   
    return FileVisitResult.SKIP_SUBTREE;
}
4

2 回答 2

2

如果您正在遍历整个目录 System 并且出现某种类型的异常,AccessDeniedException并且您希望跳过该文件,以便您可以检查需要覆盖的其他文件visitFileFailed跳过该文件或目录。

@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
    System.err.printf("Visiting failed for %s\n", file);
    return FileVisitResult.SKIP_SUBTREE;
} 

这是我在浏览目录系统时发现的解决方法。

于 2018-09-19T08:20:13.750 回答
0

尽管覆盖visitFileFailed解决了您的问题,但它可能隐藏了您仍然做错几件事的事实:

  1. Files.getFileAttributeView可以返回 null(例如,如果文件系统不支持 POSIX 文件权限)posixView.readAttributes()在 NPE 上失败
  2. posixView.readAttributes()本身可以抛出异常(例如,如果您没有读取文件权限所需的权限) - 这可能是AccessDeniedException您得到的原因
  3. 并非完全错误,但比较权限的字符串表示形式可能不适合此用例,除非您想明确检查文件是否具有给定的权限 - 并且没有其他权限;另一种方法是仅检查所需的权限:

    Set<PosixFilePermission> perm = posixAttr.permissions();
    if (perm.contains(OWNER_READ) || perm.contains(GROUP_READ) || perm.contains(OTHERS_READ)) {
        return FileVisitResult.SKIP_SUBTREE;
    }
    
于 2018-04-03T11:01:54.167 回答