From a5e9f119b67ca57e568f80c84c90f570a5e52164 Mon Sep 17 00:00:00 2001 From: Looly Date: Mon, 9 Dec 2019 17:48:25 +0800 Subject: [PATCH] fix watch --- .../cn/hutool/core/io/watch/WatchMonitor.java | 143 ++---------------- .../cn/hutool/core/io/watch/WatchServer.java | 4 +- .../cn/hutool/core/io/WatchMonitorTest.java | 2 +- 3 files changed, 13 insertions(+), 136 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/io/watch/WatchMonitor.java b/hutool-core/src/main/java/cn/hutool/core/io/watch/WatchMonitor.java index 1f5d48f6f..b6daa324e 100644 --- a/hutool-core/src/main/java/cn/hutool/core/io/watch/WatchMonitor.java +++ b/hutool-core/src/main/java/cn/hutool/core/io/watch/WatchMonitor.java @@ -2,23 +2,22 @@ package cn.hutool.core.io.watch; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IORuntimeException; -import cn.hutool.core.io.IoUtil; import cn.hutool.core.io.watch.watchers.WatcherChain; -import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.URLUtil; -import java.io.Closeable; import java.io.File; import java.io.IOException; -import java.io.Serializable; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; -import java.nio.file.*; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.Map; +import java.nio.file.Files; +import java.nio.file.LinkOption; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardWatchEventKinds; +import java.nio.file.WatchEvent; +import java.nio.file.WatchService; /** * 路径监听器 @@ -30,7 +29,7 @@ import java.util.Map; * * @author Looly */ -public class WatchMonitor extends Thread implements Closeable, Serializable { +public class WatchMonitor extends WatchServer { private static final long serialVersionUID = 1L; /** @@ -72,33 +71,10 @@ public class WatchMonitor extends Thread implements Closeable, Serializable { */ private Path filePath; - /** - * 监听服务 - */ - private WatchService watchService; /** * 监听器 */ private Watcher watcher; - /** - * 监听事件列表 - */ - private WatchEvent.Kind[] events; - /** - * 监听选项,例如监听频率等 - */ - private WatchEvent.Modifier[] modifiers; - - /** - * 监听是否已经关闭 - */ - private boolean isClosed; - - /** - * WatchKey 和 Path的对应表 - */ - private Map watchKeyPathMap = new HashMap<>(); - //------------------------------------------------------ Static method start /** @@ -369,14 +345,7 @@ public class WatchMonitor extends Thread implements Closeable, Serializable { this.path = this.filePath.getParent(); } - //初始化监听 - try { - watchService = FileSystems.getDefault().newWatchService(); - } catch (IOException e) { - throw new WatchException(e); - } - - isClosed = false; + super.init(); } /** @@ -441,31 +410,6 @@ public class WatchMonitor extends Thread implements Closeable, Serializable { return this; } - /** - * 设置监听选项,例如监听频率等,可设置项包括: - * - *
-	 * 1、com.sun.nio.file.StandardWatchEventKinds
-	 * 2、com.sun.nio.file.SensitivityWatchEventModifier
-	 * 
- * - * @param modifiers 监听选项,例如监听频率等 - * @return this - */ - public WatchMonitor setModifiers(WatchEvent.Modifier[] modifiers) { - this.modifiers = modifiers; - return this; - } - - /** - * 关闭监听 - */ - @Override - public void close() { - isClosed = true; - IoUtil.close(watchService); - } - //------------------------------------------------------ private method start /** @@ -474,36 +418,7 @@ public class WatchMonitor extends Thread implements Closeable, Serializable { * @param watcher {@link Watcher} */ private void doTakeAndWatch(Watcher watcher) { - WatchKey wk; - try { - wk = watchService.take(); - } catch (InterruptedException | ClosedWatchServiceException e) { - // 用户中断 - return; - } - - final Path currentPath = watchKeyPathMap.get(wk); - WatchEvent.Kind kind; - for (WatchEvent event : wk.pollEvents()) { - kind = event.kind(); - - // 如果监听文件,检查当前事件是否与所监听文件关联 - if (null != this.filePath && false == this.filePath.endsWith(event.context().toString())) { -// log.debug("[{}] is not fit for [{}], pass it.", event.context(), this.filePath.getFileName()); - continue; - } - - if (kind == StandardWatchEventKinds.ENTRY_CREATE) { - watcher.onCreate(event, currentPath); - } else if (kind == StandardWatchEventKinds.ENTRY_MODIFY) { - watcher.onModify(event, currentPath); - } else if (kind == StandardWatchEventKinds.ENTRY_DELETE) { - watcher.onDelete(event, currentPath); - } else if (kind == StandardWatchEventKinds.OVERFLOW) { - watcher.onOverflow(event, currentPath); - } - } - wk.reset(); + super.watch(watcher, watchEvent -> null == filePath || filePath.endsWith(watchEvent.context().toString())); } /** @@ -512,43 +427,5 @@ public class WatchMonitor extends Thread implements Closeable, Serializable { private void registerPath() { registerPath(this.path, (null != this.filePath) ? 0 : this.maxDepth); } - - /** - * 将指定路径加入到监听中 - * - * @param path 路径 - * @param maxDepth 递归下层目录的最大深度 - */ - private void registerPath(Path path, int maxDepth) { - final WatchEvent.Kind[] kinds = ArrayUtil.defaultIfEmpty(this.events, EVENTS_ALL); - - try { - final WatchKey key; - if (ArrayUtil.isEmpty(this.modifiers)) { - key = path.register(this.watchService, kinds); - } else { - key = path.register(this.watchService, kinds, this.modifiers); - } - watchKeyPathMap.put(key, path); - - // 递归注册下一层层级的目录 - if (maxDepth > 1) { - //遍历所有子目录并加入监听 - Files.walkFileTree(path, EnumSet.noneOf(FileVisitOption.class), maxDepth, new SimpleFileVisitor() { - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { - registerPath(dir, 0);//继续添加目录 - return super.postVisitDirectory(dir, exc); - } - }); - } - } catch (IOException e) { - if (e instanceof AccessDeniedException) { - //对于禁止访问的目录,跳过监听 - return; - } - throw new WatchException(e); - } - } //------------------------------------------------------ private method end } diff --git a/hutool-core/src/main/java/cn/hutool/core/io/watch/WatchServer.java b/hutool-core/src/main/java/cn/hutool/core/io/watch/WatchServer.java index 65baba9f5..57ee1f4af 100644 --- a/hutool-core/src/main/java/cn/hutool/core/io/watch/WatchServer.java +++ b/hutool-core/src/main/java/cn/hutool/core/io/watch/WatchServer.java @@ -39,7 +39,7 @@ public class WatchServer extends Thread implements Closeable, Serializable { /** * 监听事件列表 */ - private WatchEvent.Kind[] events; + protected WatchEvent.Kind[] events; /** * 监听选项,例如监听频率等 */ @@ -47,7 +47,7 @@ public class WatchServer extends Thread implements Closeable, Serializable { /** * 监听是否已经关闭 */ - private boolean isClosed; + protected boolean isClosed; /** * WatchKey 和 Path的对应表 */ diff --git a/hutool-core/src/test/java/cn/hutool/core/io/WatchMonitorTest.java b/hutool-core/src/test/java/cn/hutool/core/io/WatchMonitorTest.java index d7e7ced6f..9ce40ebea 100644 --- a/hutool-core/src/test/java/cn/hutool/core/io/WatchMonitorTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/io/WatchMonitorTest.java @@ -44,7 +44,7 @@ public class WatchMonitorTest { } }; - WatchMonitor monitor = WatchMonitor.createAll("d:/aaa/aaa.txt", new DelayWatcher(watcher, 500)); + WatchMonitor monitor = WatchMonitor.createAll("d:/test/aaa.txt", new DelayWatcher(watcher, 500)); monitor.setMaxDepth(0); monitor.start();