Мониторинг вложенных папок с помощью службы часовых поясов Java

Я использую watchKey для прослушивания изменения файла в определенной папке.

Path _directotyToWatch = Paths.get("E:/Raja");
WatchService watcherSvc = FileSystems.getDefault().newWatchService();
WatchKey watchKey = _directotyToWatch.register(watcherSvc, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);

while (true) {
    watchKey=watcherSvc.take();
    for (WatchEvent<?> event: watchKey.pollEvents()) {
        WatchEvent<Path> watchEvent = castEvent(event);
        System.out.println(event.kind().name().toString() + " " + _directotyToWatch.resolve(watchEvent.context()));
        watchKey.reset();
    }
}


Он отлично работает для меня. Если я изменяю файл в папке raja, он дает мне имя файла с контуром. Но, когда я помещаю некоторые файлы в подпапки, такие как "E:/Raja/Test", он дает мне только путь, куда я его помещаю, а не имя файла.

Как получить имя файла?

Ответ 1

Причина почему, что вы не получаете имя файла, созданное/измененное внутри подпапки, дается Stephen C в его ответе .

Вот простой пример how для регистрации каталогов и подкаталогов для просмотра их для интересующих вас событий:

/**
 * Register the given directory, and all its sub-directories, with the WatchService.
 */
private void registerAll(final Path start) throws IOException {
    // register directory and sub-directories
    Files.walkFileTree(start, new SimpleFileVisitor<Path>() {

        @Override
        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
            throws IOException {
                dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
                return FileVisitResult.CONTINUE;
        }

    });

}

Ознакомьтесь с официальными учебниками по Java: Просмотр каталога изменений. Там вы можете найти очень хорошие объяснения и примеры с исходным кодом.

В частности, вам будет интересен этот пример того, как смотреть каталог (или дерево каталогов) для изменений в файлах: WatchDir.

Метод, приведенный выше, был взят из этого примера (для краткости опущены некоторые части).
Прочтите учебник для деталей.

Ответ 2

Причина, по которой вы видите событие для "E:/Raja/Test", а не "E:/Raja/Test/Foo.txt" (например), состоит в том, что вы только зарегистрировали "E:/Raja" со службой. Это означает, что вы увидите события в каталоге и его ближайших членов. "E:/Raja/Test" является членом каталога, и вы получаете события, чтобы сказать, что это было изменено... когда файлы добавлены к нему.

Решение состоит в том, чтобы зарегистрировать все поддиректории "E:/Raja", а также... так далеко от иерархии каталогов, как вам нужно.

Ответ 3

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

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

Когда вы получите ENTRY_MODIFY, сравните время последнего изменения.

Не забудьте обновить свой список.