Событие запускается только один раз при просмотре каталога
использование java.nio наблюдая за сервисом, я пытаюсь посмотреть каталог и все его подкаталоги:
Files.walkFileTree(projectPath, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
WatchKey key = dir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE);
watched.put(key, new WatchableDirectory(dir, projectPath));
return FileVisitResult.CONTINUE;
}
});
тогда я жду событий:
executor.submit(new Runnable() {
@Override
public void run() {
try {
WatchKey key;
while ((key = watcher.take()) != null) {
List<WatchEvent<?>> events = key.pollEvents();
WatchableDirectory watchableDirectory = watched.get(key);
for (WatchEvent<?> event : events) {
....
}
}
....
}
}
(watched
это Map
который содержит сопоставления из ключа в метаданные о каталоге)
однако запускается только первое событие для данного каталога. Всякий раз, когда я изменяю другой файл в каталоге, где файл уже был изменен, ничего не происходит (я проверяю это, помещая точка останова и ожидание логики в for-loop).
однако, если я изменяю файл в другом каталоге, то все работает (опять же, только в первый раз).
исключений не возникает (есть предложение catch для java.lang.Exception
), и цикл, очевидно, продолжает работать.
Я думал, что, вероятно, после потребления, каталог может быть снят с регистрации. Поэтому я добавил строку для повторной регистрации после обработки файла. Нет эффект.
Windows 7, Java 7.
любые идеи, почему?
1 ответов
не забудьте позвонить
key.reset();
после того, как вы закончите использовать его в своем while
петли.
на docs государство
в противном случае, если есть отложенные события для объекта, то эти часы ключ немедленно ставится в очередь к службе наблюдения. Если нет ожидающие события, то ключ watch помещается в состояние готовности и будет оставайтесь в этом состоянии до тех пор, пока не будет обнаружено событие или ключ часов отмененный.
и
ключи вахты безопасны для пользы множественными одновременными потоками. Где существует несколько потоков, извлекающих сигнальные ключи из часов затем следует позаботиться о том, чтобы метод reset был вызывается только после обработки событий для объекта. Этот гарантирует, что один поток обрабатывает события для объекта в любом время.
Так что если вы не сбросите, это как если бы ваш часы отключены.
WatchKey#reset()
возвращает логическое значение, если он действует или нет. Обработайте этот случай, как описано в учебник.
Марко подчеркивает:
после того как события для ключа были обработаны, вам нужно положить ключ обратно в состояние готовности, вызвав reset. Если этот метод возвращает false, ключ больше не действителен, и цикл может выйти. Этот шаг очень важно. Если вы не вызовите reset, этот ключ не получит любые дальнейшие события.