import java.io.*;
import java.nio.file.*;
public class Tmp {
public static void main(String [] args) throws IOException {
int count = 0;
Path path = Paths.get("C:\\tmp\\");
WatchService ws = null;
try {
ws = FileSystems.getDefault().newWatchService();
path.register(ws, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE,
StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.OVERFLOW);
} catch (IOException ioe) {
ioe.printStackTrace();
}
while(true) {
WatchKey key = null;
try {
key = ws.take();
} catch(InterruptedException ie) {
ie.printStackTrace();
}
for(WatchEvent<?> event: key.pollEvents()) {
switch(event.kind().name()) {
case "OVERFLOW":
System.out.println(++count + ": OVERFLOW");
break;
case "ENTRY_MODIFY":
System.out.println(++count + ": File " + event.context() + " is changed!");
break;
case "ENTRY_CREATE":
System.out.println(++count + ": File " + event.context() + " is created!");
break;
case "ENTRY_DELETE":
System.out.println(++count + ": File " + event.context() + " is deleted!");
break;
default:
System.out.println(++count + ": UNKNOWN EVENT!");
}
}
key.reset();
}
}
}
当我运行它然后打开Notepad ++然后创建一个新的空文件并将其保存为a.txt
目录中我得到了输出:
C:\tmp\
为什么?看起来文件已创建然后被删除然后再次创建。为什么呢?
当我在文件中放入一些文本并保存时,输出为:
1: File a.txt is created!
2: File a.txt is deleted!
3: File a.txt is created!
为什么会改变两次?
答案 0 :(得分:1)
Watch Service的Modify事件会生成两个事件。当我们修改现有文件时,文件系统首先使用0字节创建它并触发修改事件然后在其上写入数据。然后它再次触发修改事件。这就是它显示两个修改事件的原因。所以我已经做了什么来解决这个问题,我只是使用计数器来检查我的任务应该只在偶数上触发一次
Path path = null;
int count = 0;
try {
path = Paths.get(new Utility().getConfDirPath());
System.out.println("Path: " + path);
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
WatchService watchService = null;
try {
watchService = FileSystems.getDefault().newWatchService();
path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY,StandardWatchEventKinds.ENTRY_DELETE);
} catch (IOException ioe) {
ioe.printStackTrace();
}
while(true) {
WatchKey key = null;
try {
key = watchService.take();
} catch(InterruptedException ie) {
ie.printStackTrace();
}
for(WatchEvent<?> event: key.pollEvents()) {
switch(event.kind().name()) {
case "ENTRY_MODIFY":
System.out.println(++count + ": File " + event.context() + " is changed!");
if (count%2==0) {
doOnChange(); // do whatever you want
}
break;
case "ENTRY_DELETE":
System.out.println(++count + ": File " + event.context() + " is deleted!");
break;
default:
System.out.println(++count + ": UNKNOWN EVENT!");
}
}
// reset the key
boolean valid = key.reset();
if (!valid) {
System.out.println("Key has been unregistered");
}
}
答案 1 :(得分:0)
文件创建和删除事件在我的系统中正常工作(Window 7 + 1.7.0_21)。
更改事件消息显示该文件上每个 Ctrl + s 操作的时间(n)。
// Removed the "//" after director name as D://tmp"
//Added just to see the message with a 1 ms gap.
Thread.sleep(1000); // after key.reset();
示例: 如果我们打开文件并继续按下crtl + s(保存没有任何更改/更改)。对于每个保存操作,将显示(重复)以下消息。
File YourFileName.txt is changed!
原因是在Windows中,WatchService将文件更改与时间戳而不是校验和进行比较。
此处提供更多说明Platform dependencies
答案 2 :(得分:0)
这对我有用
// get the first event before looping
WatchKey key = this.watcher.take();
// reset key (executed twice but not invoke the polled events)
while (key != null && key.reset() ) {
// polled events
for (final WatchEvent<?> event : key.pollEvents()) {
System.out.printf("\nGlobal received: %s, event for file: %s\n", event.kind(),
event.context());
switch (event.kind().name()) {
case "ENTRY_CREATE":
LOGGER.debug("event ENTRY_CREATE");
break;
case "ENTRY_DELETE":
LOGGER.debug("event ENTRY_DELETE");
break;
case "ENTRY_MODIFY":
LOGGER.debug("event ENTRY_MODIFY");
break;
default:
LOGGER.debug("event other [OVERFLOW]");
break;
}
}
key = this.watcher.take();
}
答案 3 :(得分:0)
我创建了一个小的FileWatcher实用程序库: https://github.com/finsterwalder/fileutils
允许设置宽限期。宽限期内的多个事件将被累积并仅触发一次。
您不应该使用Notepad ++进行实验,因为您不知道Notepad ++正在做什么。可能是,Notepad ++实际上是多次写入文件。或者它可以写一个具有不同名称的文件并重命名,完成后或诸如此类的东西。 编写自己的代码来操作文件并观察它。