All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.xiaoleilu.hutool.io.watch.watchers.DelayWatcher Maven / Gradle / Ivy

package com.xiaoleilu.hutool.io.watch.watchers;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.WatchEvent;
import java.nio.file.WatchService;
import java.util.Set;

import com.xiaoleilu.hutool.collection.ConcurrentHashSet;
import com.xiaoleilu.hutool.io.watch.Watcher;
import com.xiaoleilu.hutool.lang.Assert;
import com.xiaoleilu.hutool.thread.ThreadUtil;

/**
 * 延迟观察者
* 使用此观察者通过定义一定的延迟时间,解决{@link WatchService}多个modify的问题
* 在监听目录或文件时,如果这个文件有修改操作,会多次触发modify方法。
* 此类通过维护一个Set将短时间内相同文件多次modify的事件合并处理触发,从而避免以上问题。 * * @author Looly * @since 3.1.0 */ public class DelayWatcher implements Watcher { /** Path集合。此集合用于去重在指定delay内多次触发的文件Path */ private final Set eventSet = new ConcurrentHashSet<>(); /** 实际处理 */ private final Watcher watcher; /** 延迟,单位毫秒 */ private final long delay; //---------------------------------------------------------------------------------------------------------- Constructor start /** * 构造 * @param watcher 实际处理触发事件的监视器{@link Watcher},不可以是{@link DelayWatcher} * @param delay 延迟时间,单位毫秒 */ public DelayWatcher(Watcher watcher, long delay) { Assert.notNull(watcher); if(watcher instanceof DelayWatcher) { throw new IllegalArgumentException("Watcher must not be a DelayWatcher"); } this.watcher = watcher; this.delay = delay; } //---------------------------------------------------------------------------------------------------------- Constructor end @Override public void onModify(WatchEvent event, Path currentPath) { if(this.delay < 1) { this.watcher.onModify(event, currentPath); }else { onDelayModify(event, currentPath); } } @Override public void onCreate(WatchEvent event, Path currentPath) { watcher.onCreate(event, currentPath); } @Override public void onDelete(WatchEvent event, Path currentPath) { watcher.onDelete(event, currentPath); } @Override public void onOverflow(WatchEvent event, Path currentPath) { watcher.onOverflow(event, currentPath); } //---------------------------------------------------------------------------------------------------------- Private method start /** * 触发延迟修改 * @param event 事件 * @param currentPath 事件发生的当前Path路径 */ private void onDelayModify(WatchEvent event, Path currentPath) { Path eventPath = Paths.get(currentPath.toString(), event.context().toString()); if(eventSet.contains(eventPath)) { //此事件已经被触发过,后续事件忽略,等待统一处理。 return; } //事件第一次触发,此时标记事件,并启动处理线程延迟处理,处理结束后会删除标记 eventSet.add(eventPath); startHandleModifyThread(event, currentPath); } /** * 开启处理线程 * * @param event 事件 * @param currentPath 事件发生的当前Path路径 */ private void startHandleModifyThread(final WatchEvent event, final Path currentPath) { ThreadUtil.execute(new Runnable(){ @Override public void run() { ThreadUtil.sleep(delay); eventSet.remove(Paths.get(currentPath.toString(), event.context().toString())); watcher.onModify(event, currentPath); } }); } //---------------------------------------------------------------------------------------------------------- Private method end }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy