如何递归搜索文件并跳过权限不足的文件?

时间:2018-06-30 19:08:06

标签: java file recursion

因此,我最近发布了一个递归搜索文件时收到的错误,这是因为我需要超级用户特权才能查看文件。我对此并不真正感兴趣,所以我环顾了网上,最好的选择是使用try/catch语句,但是问题在于我正在使用的方法(如下所示)将停止如果出现错误,则完全删除,然后再次启动,则它将完全重新启动。

所以这是代码:

Files.walk(Paths.get("C:\\"))
     .filter(Files::isRegularFile)
     .forEach(System.out::println);

如何跳过我没有足够权限查看的文件?

2 个答案:

答案 0 :(得分:1)

使用访客代替步行。这样即使发生故障也可以继续进行。我在给出类似错误的linux文件上尝试了此操作。您可以在Windows中尝试相同的操作。

private static final class ExSafeVisitor extends SimpleFileVisitor<Path>
{
    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException
    {
        if (Files.isReadable(dir))
        {
            return FileVisitResult.CONTINUE;
        }
        else
        {
            return FileVisitResult.SKIP_SUBTREE;
        }
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException
    {
        if (Files.isReadable(file))
        {
            System.out.println("file = " + file);
        }
        return FileVisitResult.CONTINUE;
    }

    @Override
    //print exception but proceed
    public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException
    {
        exc.printStackTrace();
        return FileVisitResult.CONTINUE;
    }
}

//Files.walk for this path in linux throws exception
Files.walkFileTree(Paths.get("/sys/kernel"), new ExSafeVisitor());

答案 1 :(得分:0)

  

如何跳过我没有足够权限查看的文件?

您不能

您必须实际尝试读取文件,以了解是否可以实际读取文件。参见How to check if a file is readable?

通常,“使用X查看我是否可以做Y”从根本上是错误的方法。 X不是Y,因此成功执行X并不意味着Y会工作,也不会X失败表示Y会失败。与the linked question shows一样,Java的isReadable()的任何版本都不会给您关于是否可以实际读取文件的明确结果。

第二,即使您以某种方式提出了实际上是完美的检查(您也不会这样做,因为例如,您甚至看不到任何可能适用的SELinux规则... ),您仍然有一个TOCTOU bug-情况有所改变。

The isReadable() documentation甚至声明:

  

请注意,此方法的结果立即过时了,不能保证随后打开文件进行读取的尝试都会成功

仅仅是因为您的支票上说您可以读取文件,但这并不意味着您可以在尝试时实际读取文件。

确定您可以实际读取文件的唯一确定方法是实际读取该文件。在实际尝试打开文件进行读取之前所做的任何检查只会增加无用的开销。

您仍然必须在代码的任何位置正确处理异常。