JDK1.7 file monitor --- watch service api
2015-07-16 21:48
573 查看
在java.nio.file包中还提供了一套监视文件系统变更的WatchService API。可以使用这些API把一个目录注册到监视服务上。在注册的时候需要指定我们感兴趣的事件类型,比如文件创建、文件修改、文件删除等。当监视的事件发生时,监视服务会根据需要处理这些事件。
WatchService是一个接口,在不同的操作系统上有不同的实现,在Windows系统上,具体的实现为 sun.nio.fs.WindowsWatchService,在Linux平台上具体实现为sun.nio.fs.LinuxFileSystem。接着把一个或者若干个监视对象注册到监控服务上,任何实现Watchable接口的对象都可以注册。
我们使用实现该接口的Path类来注册监控服务,Path 类实现了接口的register(WatchService, WatchEvent.Kind<?>...) 方法。在注册的时候需要指定想要监视的事件类型,所支持的事件类型如下:
ENTRY_CREATE:创建条目时返回的事件类型
ENTRY_DELETE:删除条目时返回的事件类型
ENTRY_MODIFY:修改条目时返回的事件类型
OVERFLOW:事件丢失或者被丢弃,不必要注册该事件类型
下面是具体的代码示例:
Java代码
import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
import static java.nio.file.StandardWatchEventKinds.OVERFLOW;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import static java.nio.file.LinkOption.NOFOLLOW_LINKS;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class MonitorDir {
Map<WatchKey,Path> keys = new ConcurrentHashMap<WatchKey,Path>();
private static WatchService watcher = null;
static {
try {
watcher = FileSystems.getDefault().newWatchService();
} catch (IOException e) {
e.printStackTrace();
}
}
private void register(Path dir) throws IOException { // IOException ,InterruptedException{
WatchKey key = dir.register(watcher, ENTRY_CREATE,ENTRY_DELETE,ENTRY_MODIFY);
Path existing = keys.get(key);
if (existing == null) {
System.out.format("register: %s\n", dir);
} else if (!dir.equals(existing)){
System.out.format("update: %s -> %s\n",existing, dir);
}
keys.put(key, dir);
}
@SuppressWarnings("unchecked")
static <T> WatchEvent<Path> cast(WatchEvent<?> event) {
return (WatchEvent<Path>)event;
}
private void monitor(Path dir) throws IOException,InterruptedException{
register(dir);
// 等待监视事件发生
WatchKey key = watcher.take();
// System.out.println(key.getClass().getName());
Path path = keys.get(key);
if (path == null) {
return;
}
for (WatchEvent<?> event : key.pollEvents()) {
WatchEvent.Kind kind = event.kind();
if (kind == OVERFLOW) {
continue;
}
// 目录监视事件的上下文是文件名
WatchEvent<Path> evt = cast(event);
Path name = evt.context();
Path child = path.resolve(name);
System.out.format(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) + " %s|%s\n", event.kind().name(), child);
}
// 重置 key
boolean valid = key.reset();
if (!valid) {
keys.remove(key);
if (keys.isEmpty()) {
return;
}
}
}
public static void main(String[] args) {
MonitorDir monitorDir = new MonitorDir();
Path dir = Paths.get("f:/monitortest");
try {
monitorDir.monitor(dir);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
WatchService是一个接口,在不同的操作系统上有不同的实现,在Windows系统上,具体的实现为 sun.nio.fs.WindowsWatchService,在Linux平台上具体实现为sun.nio.fs.LinuxFileSystem。接着把一个或者若干个监视对象注册到监控服务上,任何实现Watchable接口的对象都可以注册。
我们使用实现该接口的Path类来注册监控服务,Path 类实现了接口的register(WatchService, WatchEvent.Kind<?>...) 方法。在注册的时候需要指定想要监视的事件类型,所支持的事件类型如下:
ENTRY_CREATE:创建条目时返回的事件类型
ENTRY_DELETE:删除条目时返回的事件类型
ENTRY_MODIFY:修改条目时返回的事件类型
OVERFLOW:事件丢失或者被丢弃,不必要注册该事件类型
下面是具体的代码示例:
Java代码
import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
import static java.nio.file.StandardWatchEventKinds.OVERFLOW;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import static java.nio.file.LinkOption.NOFOLLOW_LINKS;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class MonitorDir {
Map<WatchKey,Path> keys = new ConcurrentHashMap<WatchKey,Path>();
private static WatchService watcher = null;
static {
try {
watcher = FileSystems.getDefault().newWatchService();
} catch (IOException e) {
e.printStackTrace();
}
}
private void register(Path dir) throws IOException { // IOException ,InterruptedException{
WatchKey key = dir.register(watcher, ENTRY_CREATE,ENTRY_DELETE,ENTRY_MODIFY);
Path existing = keys.get(key);
if (existing == null) {
System.out.format("register: %s\n", dir);
} else if (!dir.equals(existing)){
System.out.format("update: %s -> %s\n",existing, dir);
}
keys.put(key, dir);
}
@SuppressWarnings("unchecked")
static <T> WatchEvent<Path> cast(WatchEvent<?> event) {
return (WatchEvent<Path>)event;
}
private void monitor(Path dir) throws IOException,InterruptedException{
register(dir);
// 等待监视事件发生
WatchKey key = watcher.take();
// System.out.println(key.getClass().getName());
Path path = keys.get(key);
if (path == null) {
return;
}
for (WatchEvent<?> event : key.pollEvents()) {
WatchEvent.Kind kind = event.kind();
if (kind == OVERFLOW) {
continue;
}
// 目录监视事件的上下文是文件名
WatchEvent<Path> evt = cast(event);
Path name = evt.context();
Path child = path.resolve(name);
System.out.format(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) + " %s|%s\n", event.kind().name(), child);
}
// 重置 key
boolean valid = key.reset();
if (!valid) {
keys.remove(key);
if (keys.isEmpty()) {
return;
}
}
}
public static void main(String[] args) {
MonitorDir monitorDir = new MonitorDir();
Path dir = Paths.get("f:/monitortest");
try {
monitorDir.monitor(dir);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
相关文章推荐
- [leetcode-210]course scheduleII(java)
- 以Java属性文件的格式创建Hibernate的配置文件和DTD特殊符号作用
- JAVA程序运行时 对象的放置安排及内存的分配
- Eclipse如何设置字体
- Eclipse常用快捷键
- Java并发编程:Callable、Future和FutureTask
- Java - 初始化
- 有效检查Java代码的工具:5款调试工具
- Java锁的种类
- Java--动态代理
- 如何在struts2的action返回结果之后再来进行费时的数据库操作呢?
- spring security (-) helloWorld
- Java中判断字符串是否为数字的五种方法
- spring系列文章(一)AOP源码分析
- java时间格式化问题
- eclipse项目里面的类有时候会莫名其妙出现很多错误
- #笔记#圣思园 JavaWeb 第42讲——Listener监听器,观察者模式
- java的重载
- day02--Java中数组工具类:Arrays
- JAVA 对象引用,以及对象赋值