【www.bbyears.com--说说】
Java 7之前的版本都是没有原生支持的,下面就说说JDK 1.7 以下版本平台的解决方案:
事件驱动方式,无需无目录扫描,但与平台相关
线程轮询扫描,纯java实现,完美跨平台,但监听文件较多时,扫描的量太大,响应不是非常及时,依赖于扫描间隔时间
JNotify属于事件驱动,所以不同的平台的处理方式不一样。所以需要在java.library.path里面添加jnotify.dll/jnotify_64bit.dll,最简单的解决方案直接修改代码。JNotify_win32.java的47和51行的System.loadLibrary改为System.load(dllpath),其他平台的修改也是一样的。然后把dll,so文件导成jar包,世界就清静了。
使用非常简单,示例代码如下
代码如下public static void main(String[] args) throws InterruptedException, IOException {
String dir = new File(args.length == 0 ? "." : args[0]).getCanonicalFile().getAbsolutePath();
JNotify.addWatch(dir, FILE_ANY, true, new JNotifyListener() {
public void fileRenamed(int wd, String rootPath, String oldName, String newName) {
System.out.println("renamed " + rootPath + " : " + oldName + " -> " + newName);
}
public void fileModified(int wd, String rootPath, String name) {
System.out.println("modified " + rootPath + " : " + name);
}
public void fileDeleted(int wd, String rootPath, String name) {
System.out.println("deleted " + rootPath + " : " + name);
}
public void fileCreated(int wd, String rootPath, String name) {
System.out.println("created " + rootPath + " : " + name);
}
});
System.err.println("Monitoring " + dir + ", ctrl+c to stop");
while (true)
Thread.sleep(10000);
}
Jpathwath要写的代码稍微多点。事件说明参考这个,简单示例如下
代码如下public static void main(String[] args) {
WatchService watchService = FileSystems.getDefault().newWatchService();
Path watchedPath = Paths.get("E:/temp");
try {
WatchKey key = watchedPath.register(watchService, StandardWatchEventKind.ENTRY_MODIFY);
System.out.println(key.isValid());
} catch (UnsupportedOperationException uox) {
System.err.println("file watching not supported!");
} catch (IOException iox) {
System.err.println("I/O errors");
}
for (;;) {
// take() will block until a file has been created/deleted
WatchKey signalledKey;
try {
signalledKey = watchService.take();
} catch (InterruptedException ix) {
continue;
} catch (ClosedWatchServiceException cwse) {
System.out.println("watch service closed, terminating.");
break;
}
List
signalledKey.reset();
for (WatchEvent> e : list) {
String message = "";
if (e.kind() == StandardWatchEventKind.ENTRY_MODIFY) {
Path context = (Path) e.context();
message = context.toString() + " modified";
}
System.out.println(message);
}
}
}
需要注意的是Windows平台下,重命名一个文件,产生2个事件——重命名和修改,在事件处理的时候需要注意。