直接贴代码
package event;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.*;
/**
* @author likailong
*/
public class DirectoryWatcherImpl {
private static final Logger LOGGER = LoggerFactory.getLogger(DirectoryWatcherImpl.class);
private WatchService watchService;
private final Map<WatchKey, Path> directories = new HashMap<>();
private WatchEvent.Kind<?>[] events;
private static final ThreadFactory THREAD_FACTORY = new ThreadFactoryBuilder().setNameFormat("TtsWrapperService-pool-%d").build();
private static ExecutorService EXECUTOR = null;
private static LinkedBlockingQueue linkedBlockingQueue = new LinkedBlockingQueue<>(1024);
public void watchDirectory(String path) {
watchDirectory(Paths.get(path));
}
/**
* 监控指定目录,不监控子目录
*
* @param path
*/
public void watchDirectory(Path path) {
registerDirectory(path);
}
/**
* 监控指定的目录及其所有子目录
*
* @param path
*/
public void watchDirectoryTree(String path) {
watchDirectoryTree(Paths.get(path));
}
/**
* 监控指定的目录及其所有子目录
*
* @param path
*/
public void watchDirectoryTree(Path path) {
registerDirectoryTree(path);
}
/**
* 关闭监控线程
*/
public void close() {
EXECUTOR.shutdown();
}
private DirectoryWatcherImpl() {
}
private DirectoryWatcherImpl(final WatcherCallback watcherCallback, WatchEvent.Kind<?>... events) {
if (events.length == 0) {
throw new RuntimeException("必须传入至少一个监控事件");
}
synchronized (DirectoryWatcherImpl.class) {
EXECUTOR = new ThreadPoolExecutor(4, 20000, 0L,
TimeUnit.SECONDS, linkedBlockingQueue, THREAD_FACTORY, new ThreadPoolExecutor.AbortPolicy());
}
this.events = new WatchEvent.Kind<?>[events.length];
int i = 0;
for (WatchEvent.Kind<?> event : events) {
this.events[i++] = event;
}
try {
watchService = FileSystems.getDefault().newWatchService();
EXECUTOR.submit(() -> watch(watcherCallback));
} catch (IOException e) {
e.printStackTrace();
}
}
private void watch(WatcherCallback watcherCallback) {
while (true) {
try {
final WatchKey key = watchService.take();
if (key == null) {
continue;
}
for (WatchEvent<?> watchEvent : key.pollEvents()) {
final WatchEvent.Kind<?> kind = watchEvent.kind();
//忽略无效事件
if (kind == StandardWatchEventKinds.OVERFLOW) {
continue;
}
final WatchEvent<Path> watchEventPath = (WatchEvent<Path>) watchEvent;
//path是相对路径(相对于监控目录)
final Path contextPath = watchEventPath.context();
//获取监控目录
final Path directoryPath = directories.get(key);
//得到绝对路径
final Path absolutePath = directoryPath.resolve(contextPath);
//判断事件类别
switch (kind.name()) {
case "ENTRY_CREATE":
if (Files.isDirectory(absolutePath, LinkOption.NOFOLLOW_LINKS)) {
//为新增的目录及其所有子目录注册监控事件
registerDirectoryTree(absolutePath);
} else {
LOGGER.info("新增文件:" + absolutePath);
}
break;
case "ENTRY_DELETE":
LOGGER.info("删除:" + absolutePath);
break;
case "ENTRY_MODIFY":
LOGGER.info("修改:" + absolutePath);
break;
default:
break;
}
//业务逻辑
watcherCallback.execute(kind, absolutePath.toAbsolutePath().toString());
}
boolean valid = key.reset();
if (!valid) {
if (directories.get(key) != null) {
LOGGER.info("停止监控目录:" + directories.get(key));
directories.remove(key);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void registerDirectoryTree(Path path) {
try {
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
registerDirectory(dir);
return FileVisitResult.CONTINUE;
}
});
} catch (IOException ex) {
LOGGER.error("监控目录失败:" + path.toAbsolutePath(), ex);
}
}
private void registerDirectory(Path path) {
try {
LOGGER.info("监控目录:" + path);
WatchKey key = path.register(watchService, events);
directories.put(key, path);
} catch (IOException ex) {
LOGGER.error("监控目录失败:" + path.toAbsolutePath(), ex);
}
}
public interface WatcherCallback {
void execute(WatchEvent.Kind<?> kind, String path);
}
public static void main(String[] args) {
System.out.println("args = [" + linkedBlockingQueue.size() + "]");
DirectoryWatcherImpl dictionaryWatcher = new DirectoryWatcherImpl(new WatcherCallback() {
private long lastExecute = System.currentTimeMillis();
@Override
public void execute(WatchEvent.Kind<?> kind, String path) {
if (System.currentTimeMillis() - lastExecute > 1000) {
lastExecute = System.currentTimeMillis();
System.out.println("事件:" + kind.name() + " ,路径:" + path);
}
}
}, StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_MODIFY,
StandardWatchEventKinds.ENTRY_DELETE);
//监控DIC目录及其所有子目录的子目录...递归
dictionaryWatcher.watchDirectoryTree("/Users/likailong/Desktop");
//只监控DIC2目录
dictionaryWatcher.watchDirectory("/Users/likailong/Desktop");
}
}
版权声明:本文为likailonghaha原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。