当我尝试注册文件而不是目录时 java.nio.file.NotDirectoryException
被抛出。我可以监听单个文件更改,而不是整个目录吗?
原文由 fedor.belov 发布,翻译遵循 CC BY-SA 4.0 许可协议
当我尝试注册文件而不是目录时 java.nio.file.NotDirectoryException
被抛出。我可以监听单个文件更改,而不是整个目录吗?
原文由 fedor.belov 发布,翻译遵循 CC BY-SA 4.0 许可协议
其他答案是正确的,您必须监视一个目录并过滤您的特定文件。但是,您可能需要一个在后台运行的线程。接受的答案可以在 watchService.take();
上无限期阻塞,并且不会关闭 WatchService。适用于单独线程的解决方案可能如下所示:
public class FileWatcher extends Thread {
private final File file;
private AtomicBoolean stop = new AtomicBoolean(false);
public FileWatcher(File file) {
this.file = file;
}
public boolean isStopped() { return stop.get(); }
public void stopThread() { stop.set(true); }
public void doOnChange() {
// Do whatever action you want here
}
@Override
public void run() {
try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
Path path = file.toPath().getParent();
path.register(watcher, StandardWatchEventKinds.ENTRY_MODIFY);
while (!isStopped()) {
WatchKey key;
try { key = watcher.poll(25, TimeUnit.MILLISECONDS); }
catch (InterruptedException e) { return; }
if (key == null) { Thread.yield(); continue; }
for (WatchEvent<?> event : key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
@SuppressWarnings("unchecked")
WatchEvent<Path> ev = (WatchEvent<Path>) event;
Path filename = ev.context();
if (kind == StandardWatchEventKinds.OVERFLOW) {
Thread.yield();
continue;
} else if (kind == java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY
&& filename.toString().equals(file.getName())) {
doOnChange();
}
boolean valid = key.reset();
if (!valid) { break; }
}
Thread.yield();
}
} catch (Throwable e) {
// Log or rethrow the error
}
}
}
我尝试从接受的答案和 这篇文章 开始工作。您应该能够将此线程与 new FileWatcher(new File("/home/me/myfile")).start()
一起使用,并通过在线程上调用 stopThread()
来停止它。
原文由 timrs2998 发布,翻译遵循 CC BY-SA 3.0 许可协议
4 回答1.4k 阅读✓ 已解决
4 回答1.2k 阅读✓ 已解决
1 回答2.6k 阅读✓ 已解决
2 回答737 阅读✓ 已解决
2 回答1.7k 阅读
2 回答1.7k 阅读
2 回答1.3k 阅读
只需过滤目录中所需文件的事件:
在这里我们检查更改的文件是否是“myFile.txt”,如果是则执行任何操作。