直接贴代码
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"); } }