您的位置:首页 > 编程语言 > Java开发

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();

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: