Как рекурсивно искать файлы и пропускать тех, у кого недостаточно прав? - PullRequest
0 голосов
/ 30 июня 2018

Итак, я недавно опубликовал сообщение об ошибке, полученной при рекурсивном поиске файлов, и потому, что мне нужны были права суперпользователя для просмотра файлов. Я не очень заинтересован в этом, и поэтому я посмотрел в Интернете, и моя лучшая ставка была просто использовать заявление try/catch, но проблема в том, что метод, который я использую (см. Ниже), полностью остановится, если он получил ошибку, а затем, если я запустил его снова, он полностью перезапустился бы.

Итак, вот код:

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

Как я могу пропустить файлы, у которых недостаточно прав для просмотра?

Ответы [ 2 ]

0 голосов
/ 01 июля 2018

Как я могу пропустить файлы, у которых недостаточно прав для просмотра?

Вы не можете .

Вы должны попытаться прочитать файл, чтобы узнать, действительно ли вы можете прочитать файл. См. Как проверить, доступен ли файл для чтения?

В общем, «Использовать X, чтобы увидеть, могу ли я сделать Y», - это принципиально неверный подход. X - это не Y, поэтому успешное выполнение X не означает, что Y будет работать, а X не означает, что Y потерпит неудачу. Поскольку связанный вопрос показывает , ни одна версия Java isReadable() не даст вам окончательных результатов относительно того, действительно ли вы можете читать файл.

Во-вторых, даже если вы каким-то образом придумали проверку, которая на самом деле идеальна (вы этого не сделаете, потому что, например, вы даже не видите никаких правил SELinux , которые могут быть на месте. ..), у вас все еще есть ошибка TOCTOU - все меняется.

Документация isReadable() даже гласит:

Обратите внимание, что результат этого метода сразу устарел, нет никакой гарантии, что последующая попытка открыть файл для чтения будет успешной

Тот факт, что ваш чек сказал, что вы можете прочитать файл, не означает, что вы действительно можете прочитать файл при попытке.

Единственный окончательный способ определить, что вы действительно можете прочитать файл, - это действительно прочитать этот файл. Любые проверки, которые вы делаете перед попыткой открыть файл для чтения, просто добавляют бесполезные накладные расходы.

Вы все равно должны правильно обрабатывать исключения в любом месте вашего кода.

0 голосов
/ 30 июня 2018

Используйте посетителя вместо прогулки. Это позволяет продолжить работу даже в случае сбоя. Я попробовал это на 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());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...