Служба наблюдения Java NIO создала и ENTRY_CREATE, и ENTRY_MODIFY, когда новый файл добавляется в папку наблюдения
Я вижу странное поведение (не уверен, что это ожидаемое поведение) при использовании java.nio.file.WatchService.
Проблема в том, что у меня есть папка, зарегистрированная в WatchService. Когда я копирую новый файл в эту папку, генерируются два WatchEvent, по одному для каждого:
"ENTRY_CREATE" и "ENTRY_MODIFY".
Насколько я понимаю, новый файл (скопированный из другого каталога, который не отслеживается) должен создавать только одно событие, а именно: 'ENTRY_CREATE'.
Кто-нибудь может объяснить, почему создается дополнительное событие ENTRY_MODIFY?
Мой код:
public void watch() {
WatchKey key = watcher.poll();
//log.info("Watcher scheduler running. Watch key {}", key.hashCode());
if (key != null) {
Workflow workflow = keys.get(key);
log.info("Runing watcher for key '{}' and workflow {}", key.hashCode(), workflow.getName());
File hotFolder = new File(workflow.getFolderPath());
Path dir = hotFolder.toPath();
for (WatchEvent<?> event : key.pollEvents()) {
WatchEvent<Path> ev = cast(event);
Path name = ev.context();
Path child = dir.resolve(name);
log.info("Polling event for name {} and child {} and dir {}", name.toFile(), child.toFile(), dir.toFile());
if (Files.isDirectory(child, LinkOption.NOFOLLOW_LINKS))
continue;
try {
switch (event.kind().name()) {
case "ENTRY_CREATE":
log.info("New file {}", child.toFile());
fileService.processNewFile(child.toFile(), workflow);
break;
case "ENTRY_MODIFY":
log.info("File modified.... {}", child.toFile());
fileService.processModifiedFile(child.toFile(),
workflow);
break;
default:
log.error("Unknown event {} for file {}", event.kind()
.name(), child.toFile());
break;
}
// Operation op = Operation.from(event.kind());
// if (op != null)
// publisher.publishEvent(new FileEvent(child.toFile(),
// workflow, op));
} catch (Throwable t) {
log.warn("Error while procesing file event", t);
}
}
key.reset();
}
}
Поэтому, когда я копирую файл, скажем, name = "abc.txt", отображаются журналы:
Новый файл abc.txt
Файл изменен.... abc.txt
Любые входные данные очень востребованы.
2 ответа
Проверьте раздел "Зависимости платформы" в JavaDoc WatchService.
Наблюдатель ведет себя правильно в описанной вами ситуации. И, строго говоря, когда вы копируете файл в папку, файлы действительно создаются, а затем изменяются.
При использовании WatcherService нужно учитывать много вещей, их поведение сильно варьируется, например:
- Операционные системы
- Зашифрованные диски
- Сетевые акции
- ...
Я думаю, что вопрос уже был дан ответ здесь.
Например, Java: WatchService получает информацию перед копированием контента.
В двух словах, события генерируются вашей операционной системой. У вас есть два события, что означает, что ваша ОС выполняет копирование неатомарным способом. Если вы попытаетесь прочитать файл где-то между ENTRY_CREATE и ENTRY_MODIFY, это будет противоречиво. Но опять же, это зависит от вашей ОС. Например, в Windows 7 я получаю ENTRY_CREATE один раз и ENTRY_MODIFY два раза для больших файлов. Таким образом, вы на самом деле не можете быть уверены в том, что файл успешно скопирован или нет, вам нужно придумать метрики, зависящие от приложения / ОС.