我使用java.nio.file.WatchService.看到一个奇怪的行为(不确定这是预期的行为)
问题是我有一个在WatchService注册的文件夹。当我将一个新文件复制到这个文件夹中时,会生成两个WatchEvent,每个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
我们强烈要求您提供任何意见。
检查WatchService JavaDoc中的"平台依赖项"部分。
观察者在您描述的情况下表现正确。严格地说,当你把一个文件复制到一个文件夹时,文件实际上是创建的,然后修改。
当使用WatcherService时,有很多事情需要考虑,它的行为会有很多不同,例如:
- 操作系统
- 加密光盘
- 网络共享
我想,这个问题已经在这里得到了回答。
例如Java:WatchService在复制内容之前得到通知
换句话说,事件是由您的操作系统生成的。您有两个事件,这意味着您的操作系统以非原子方式执行复制。如果您试图读取ENTRY_CREATE和ENTRY_MODIFY之间的某个文件,则该文件将不一致。但同样,这取决于您的操作系统。例如,在Windows7上,对于大文件,我得到了一次ENTRY_CREATE和两次ENTRY_MODIFY。因此,您实际上无法确定文件是否成功复制,您必须制定与应用程序/OS相关的指标。