Java Проблема с подкаталогом Files.walkTree () - PullRequest
1 голос
/ 22 марта 2020

Моя платформа - Centos 7.0, я работаю в Java 8.

Мой вопрос заключается в том, как java .nio.file, Files.walkFileTree () следует использовать для поиска файлов в дерево каталогов, которое содержит некоторые файлы и каталоги, к которым у текущего пользователя нет прав доступа, но которое содержит много других каталогов и файлов, которые доступны. На этой диаграмме показан тип скороговорки, папки и файлы в других группах, но, как правило, общедоступный (755), поэтому моя программа может их видеть. Однако наличие одного недоступного (750) каталога, кажется, запутывает прохождение. На рисунке показан упрощенный вид.

a 755
|----- ab 755
        | ----- f1 644  <== files here found
        | ----- f2 644
|----- ac 750           <== dir not accessible
        | ----- f3 644 .<== expect not to find this
|----- ad 755
|       | ----- f4 644  <== expect to find, but not seen

Я все еще занимаюсь расследованием, но похоже, что мое приложение не работает, когда обратный путь в каталогах попадает в каталог, разрешения которого запрещают доступ. Я нахожусь в процессе создания урезанного примера, но в то же время я хотел бы проверить, обоснованы ли эти ожидания:

  1. walkFileTree () попытается посетить каждый подкаталог
  2. Если он попадает в каталог или файл, к которым нет доступа, будет вызван обратный вызов visitFileFailed (), и если эта функция вернет значение CONTINUE, то обход будет продолжен - есть другие варианты для возвращаемого значения, но пока это все нужно.
  3. Мне не нужно проверять права доступа к файлам в этих обратных вызовах

Я использую Files.walkFileTree (), а не Files.find (), потому что последний также, похоже, дает сбой при попадание в нечитаемые каталоги, и я подумал, что walkFileTree () даст мне больше контроля.

FileVisitor<Path> visitor = new FileVisitor<Path>() {

    @Override
    public FileVisitResult preVisitDirectory(Path dir, 
                            BasicFileAttributes attrs) throws IOException {
        // do I need to code something like this?           
        if ( ! dir.toFile().canRead() 
            || ! dir.toFile().canExecute()
                            ) {

                return FileVisitResult.SKIP_SUBTREE;
        } else {        
            return FileVisitResult.CONTINUE;
        }
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        // code here where I action some files, which works if I get here.      

        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
        // log error here, but carry on down the tree
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
        if ( exc != null) {
               // log error, but carry on anyway
               // in my tests we never arrive here
        }           
        return FileVisitResult.CONTINUE;
    }

};

EnumSet<FileVisitOption> opts = EnumSet.of(FileVisitOption.FOLLOW_LINKS);

try {           
    Files.walkFileTree(new File(filePath).toPath(), 
                           opts, 
                           Integer.MAX_VALUE, 
                           visitor);


} catch(Exception e) {
    // log errror here, but in my tests we don't end up here
} 

Спасибо за любую помощь здесь.

1 Ответ

0 голосов
/ 23 марта 2020

Вырезанная версия моей программы работает, как я ожидаю.

Пример здесь также работает в моей тестовой среде. Недоступные каталоги не препятствуют доступу к доступным каталогам.

Относительно того, почему моя полная программа не работает, у меня нет объяснения ...

...