This commit is contained in:
Looly 2023-12-29 11:50:07 +08:00
parent 76bcbfe67c
commit bca0f82bac
10 changed files with 71 additions and 88 deletions

View File

@ -21,6 +21,7 @@ import java.io.RandomAccessFile;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.WatchEvent; import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
/** /**
* 行处理的Watcher实现 * 行处理的Watcher实现
@ -53,7 +54,7 @@ public class LineReadWatcher extends SimpleWatcher implements Runnable {
} }
@Override @Override
public void onModify(final WatchEvent<?> event, final Path currentPath) { public void onModify(final WatchEvent<?> event, final WatchKey key) {
final RandomAccessFile randomAccessFile = this.randomAccessFile; final RandomAccessFile randomAccessFile = this.randomAccessFile;
final Charset charset = this.charset; final Charset charset = this.charset;
final SerConsumer<String> lineHandler = this.lineHandler; final SerConsumer<String> lineHandler = this.lineHandler;

View File

@ -14,14 +14,14 @@ package org.dromara.hutool.core.io.file;
import org.dromara.hutool.core.date.DateUnit; import org.dromara.hutool.core.date.DateUnit;
import org.dromara.hutool.core.exception.HutoolException; import org.dromara.hutool.core.exception.HutoolException;
import org.dromara.hutool.core.func.SerConsumer;
import org.dromara.hutool.core.io.IORuntimeException; import org.dromara.hutool.core.io.IORuntimeException;
import org.dromara.hutool.core.io.IoUtil; import org.dromara.hutool.core.io.IoUtil;
import org.dromara.hutool.core.io.watch.watchers.SimpleWatcher;
import org.dromara.hutool.core.io.watch.WatchKind; import org.dromara.hutool.core.io.watch.WatchKind;
import org.dromara.hutool.core.io.watch.WatchMonitor; import org.dromara.hutool.core.io.watch.WatchMonitor;
import org.dromara.hutool.core.io.watch.WatchUtil; import org.dromara.hutool.core.io.watch.WatchUtil;
import org.dromara.hutool.core.io.watch.watchers.SimpleWatcher;
import org.dromara.hutool.core.lang.Console; import org.dromara.hutool.core.lang.Console;
import org.dromara.hutool.core.func.SerConsumer;
import org.dromara.hutool.core.text.CharUtil; import org.dromara.hutool.core.text.CharUtil;
import org.dromara.hutool.core.util.CharsetUtil; import org.dromara.hutool.core.util.CharsetUtil;
@ -30,14 +30,10 @@ import java.io.IOException;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
import java.io.Serializable; import java.io.Serializable;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.WatchEvent; import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.util.Stack; import java.util.Stack;
import java.util.concurrent.ExecutionException; import java.util.concurrent.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
/** /**
* 文件内容跟随器实现类似Linux下"tail -f"命令功能 * 文件内容跟随器实现类似Linux下"tail -f"命令功能
@ -162,8 +158,8 @@ public class Tailer implements Serializable {
fileDeleteWatchMonitor = WatchUtil.of(this.filePath, WatchKind.DELETE.getValue()); fileDeleteWatchMonitor = WatchUtil.of(this.filePath, WatchKind.DELETE.getValue());
fileDeleteWatchMonitor.setWatcher(new SimpleWatcher(){ fileDeleteWatchMonitor.setWatcher(new SimpleWatcher(){
@Override @Override
public void onDelete(final WatchEvent<?> event, final Path currentPath) { public void onDelete(final WatchEvent<?> event, final WatchKey key) {
super.onDelete(event, currentPath); super.onDelete(event, key);
stop(); stop();
throw new IORuntimeException("{} has been deleted", filePath); throw new IORuntimeException("{} has been deleted", filePath);
} }

View File

@ -202,7 +202,7 @@ public class WatchMonitor extends Thread implements Closeable, Serializable {
} }
@Override @Override
public void close() throws IOException { public void close() {
this.watchService.close(); this.watchService.close();
} }
//------------------------------------------------------ private method end //------------------------------------------------------ private method end

View File

@ -17,10 +17,7 @@ import org.dromara.hutool.core.io.watch.Watcher;
import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.thread.ThreadUtil; import org.dromara.hutool.core.thread.ThreadUtil;
import java.nio.file.Path; import java.nio.file.*;
import java.nio.file.Paths;
import java.nio.file.WatchEvent;
import java.nio.file.WatchService;
import java.util.Set; import java.util.Set;
/** /**
@ -59,37 +56,37 @@ public class DelayWatcher implements Watcher {
//---------------------------------------------------------------------------------------------------------- Constructor end //---------------------------------------------------------------------------------------------------------- Constructor end
@Override @Override
public void onModify(final WatchEvent<?> event, final Path currentPath) { public void onModify(final WatchEvent<?> event, final WatchKey key) {
if(this.delay < 1) { if(this.delay < 1) {
this.watcher.onModify(event, currentPath); this.watcher.onModify(event, key);
}else { }else {
onDelayModify(event, currentPath); onDelayModify(event, key);
} }
} }
@Override @Override
public void onCreate(final WatchEvent<?> event, final Path currentPath) { public void onCreate(final WatchEvent<?> event, final WatchKey key) {
watcher.onCreate(event, currentPath); watcher.onCreate(event, key);
} }
@Override @Override
public void onDelete(final WatchEvent<?> event, final Path currentPath) { public void onDelete(final WatchEvent<?> event, final WatchKey key) {
watcher.onDelete(event, currentPath); watcher.onDelete(event, key);
} }
@Override @Override
public void onOverflow(final WatchEvent<?> event, final Path currentPath) { public void onOverflow(final WatchEvent<?> event, final WatchKey key) {
watcher.onOverflow(event, currentPath); watcher.onOverflow(event, key);
} }
//---------------------------------------------------------------------------------------------------------- Private method start //---------------------------------------------------------------------------------------------------------- Private method start
/** /**
* 触发延迟修改 * 触发延迟修改
* @param event 事件 * @param event 事件
* @param currentPath 事件发生的当前Path路径 * @param key {@link WatchKey}
*/ */
private void onDelayModify(final WatchEvent<?> event, final Path currentPath) { private void onDelayModify(final WatchEvent<?> event, final WatchKey key) {
final Path eventPath = Paths.get(currentPath.toString(), event.context().toString()); final Path eventPath = Paths.get(key.watchable().toString(), event.context().toString());
if(eventSet.contains(eventPath)) { if(eventSet.contains(eventPath)) {
//此事件已经被触发过后续事件忽略等待统一处理 //此事件已经被触发过后续事件忽略等待统一处理
return; return;
@ -97,7 +94,7 @@ public class DelayWatcher implements Watcher {
//事件第一次触发此时标记事件并启动处理线程延迟处理处理结束后会删除标记 //事件第一次触发此时标记事件并启动处理线程延迟处理处理结束后会删除标记
eventSet.add(eventPath); eventSet.add(eventPath);
startHandleModifyThread(event, currentPath); startHandleModifyThread(event, key);
} }
/** /**
@ -106,11 +103,11 @@ public class DelayWatcher implements Watcher {
* @param event 事件 * @param event 事件
* @param currentPath 事件发生的当前Path路径 * @param currentPath 事件发生的当前Path路径
*/ */
private void startHandleModifyThread(final WatchEvent<?> event, final Path currentPath) { private void startHandleModifyThread(final WatchEvent<?> event, final WatchKey key) {
ThreadUtil.execute(() -> { ThreadUtil.execute(() -> {
ThreadUtil.sleep(delay); ThreadUtil.sleep(delay);
eventSet.remove(Paths.get(currentPath.toString(), event.context().toString())); eventSet.remove(Paths.get(key.watchable().toString(), event.context().toString()));
watcher.onModify(event, currentPath); watcher.onModify(event, key);
}); });
} }
//---------------------------------------------------------------------------------------------------------- Private method end //---------------------------------------------------------------------------------------------------------- Private method end

View File

@ -12,11 +12,11 @@
package org.dromara.hutool.core.io.watch.watchers; package org.dromara.hutool.core.io.watch.watchers;
import java.nio.file.Path;
import java.nio.file.WatchEvent;
import org.dromara.hutool.core.io.watch.Watcher; import org.dromara.hutool.core.io.watch.Watcher;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
/** /**
* 跳过所有事件处理Watcher<br> * 跳过所有事件处理Watcher<br>
* 用户继承此类后实现需要监听的方法 * 用户继承此类后实现需要监听的方法
@ -27,18 +27,18 @@ import org.dromara.hutool.core.io.watch.Watcher;
public class IgnoreWatcher implements Watcher { public class IgnoreWatcher implements Watcher {
@Override @Override
public void onCreate(final WatchEvent<?> event, final Path currentPath) { public void onCreate(final WatchEvent<?> event, final WatchKey key) {
} }
@Override @Override
public void onModify(final WatchEvent<?> event, final Path currentPath) { public void onModify(final WatchEvent<?> event, final WatchKey key) {
} }
@Override @Override
public void onDelete(final WatchEvent<?> event, final Path currentPath) { public void onDelete(final WatchEvent<?> event, final WatchKey key) {
} }
@Override @Override
public void onOverflow(final WatchEvent<?> event, final Path currentPath) { public void onOverflow(final WatchEvent<?> event, final WatchKey key) {
} }
} }

View File

@ -12,8 +12,6 @@
package org.dromara.hutool.core.io.watch.watchers; package org.dromara.hutool.core.io.watch.watchers;
import org.dromara.hutool.core.io.watch.watchers.IgnoreWatcher;
/** /**
* 空白WatchListener<br> * 空白WatchListener<br>
* 用户继承此类后实现需要监听的方法 * 用户继承此类后实现需要监听的方法
@ -21,5 +19,4 @@ import org.dromara.hutool.core.io.watch.watchers.IgnoreWatcher;
* *
*/ */
public class SimpleWatcher extends IgnoreWatcher { public class SimpleWatcher extends IgnoreWatcher {
} }

View File

@ -15,8 +15,8 @@ package org.dromara.hutool.core.io.watch.watchers;
import org.dromara.hutool.core.io.watch.Watcher; import org.dromara.hutool.core.io.watch.Watcher;
import org.dromara.hutool.core.lang.Chain; import org.dromara.hutool.core.lang.Chain;
import java.nio.file.Path;
import java.nio.file.WatchEvent; import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.util.Arrays; import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -51,30 +51,30 @@ public class WatcherChain implements Watcher, Chain<Watcher, WatcherChain> {
} }
@Override @Override
public void onCreate(final WatchEvent<?> event, final Path currentPath) { public void onCreate(final WatchEvent<?> event, final WatchKey key) {
for (final Watcher watcher : chain) { for (final Watcher watcher : chain) {
watcher.onCreate(event, currentPath); watcher.onCreate(event, key);
} }
} }
@Override @Override
public void onModify(final WatchEvent<?> event, final Path currentPath) { public void onModify(final WatchEvent<?> event, final WatchKey key) {
for (final Watcher watcher : chain) { for (final Watcher watcher : chain) {
watcher.onModify(event, currentPath); watcher.onModify(event, key);
} }
} }
@Override @Override
public void onDelete(final WatchEvent<?> event, final Path currentPath) { public void onDelete(final WatchEvent<?> event, final WatchKey key) {
for (final Watcher watcher : chain) { for (final Watcher watcher : chain) {
watcher.onDelete(event, currentPath); watcher.onDelete(event, key);
} }
} }
@Override @Override
public void onOverflow(final WatchEvent<?> event, final Path currentPath) { public void onOverflow(final WatchEvent<?> event, final WatchKey key) {
for (final Watcher watcher : chain) { for (final Watcher watcher : chain) {
watcher.onOverflow(event, currentPath); watcher.onOverflow(event, key);
} }
} }

View File

@ -12,16 +12,16 @@
package org.dromara.hutool.core.io; package org.dromara.hutool.core.io;
import java.nio.file.Path;
import java.nio.file.WatchEvent;
import org.dromara.hutool.core.io.watch.watchers.SimpleWatcher;
import org.dromara.hutool.core.io.watch.WatchMonitor; import org.dromara.hutool.core.io.watch.WatchMonitor;
import org.dromara.hutool.core.io.watch.WatchUtil; import org.dromara.hutool.core.io.watch.WatchUtil;
import org.dromara.hutool.core.io.watch.Watcher; import org.dromara.hutool.core.io.watch.Watcher;
import org.dromara.hutool.core.io.watch.watchers.DelayWatcher; import org.dromara.hutool.core.io.watch.watchers.DelayWatcher;
import org.dromara.hutool.core.io.watch.watchers.SimpleWatcher;
import org.dromara.hutool.core.lang.Console; import org.dromara.hutool.core.lang.Console;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
/** /**
* 文件监听单元测试 * 文件监听单元测试
* *
@ -33,27 +33,27 @@ public class WatchMonitorTest {
public static void main(final String[] args) { public static void main(final String[] args) {
final Watcher watcher = new SimpleWatcher(){ final Watcher watcher = new SimpleWatcher(){
@Override @Override
public void onCreate(final WatchEvent<?> event, final Path currentPath) { public void onCreate(final WatchEvent<?> event, final WatchKey key) {
final Object obj = event.context(); final Object obj = event.context();
Console.log("创建:{}-> {}", currentPath, obj); Console.log("创建:{}-> {}", key.watchable(), obj);
} }
@Override @Override
public void onModify(final WatchEvent<?> event, final Path currentPath) { public void onModify(final WatchEvent<?> event, final WatchKey key) {
final Object obj = event.context(); final Object obj = event.context();
Console.log("修改:{}-> {}", currentPath, obj); Console.log("修改:{}-> {}", key.watchable(), obj);
} }
@Override @Override
public void onDelete(final WatchEvent<?> event, final Path currentPath) { public void onDelete(final WatchEvent<?> event, final WatchKey key) {
final Object obj = event.context(); final Object obj = event.context();
Console.log("删除:{}-> {}", currentPath, obj); Console.log("删除:{}-> {}", key.watchable(), obj);
} }
@Override @Override
public void onOverflow(final WatchEvent<?> event, final Path currentPath) { public void onOverflow(final WatchEvent<?> event, final WatchKey key) {
final Object obj = event.context(); final Object obj = event.context();
Console.log("Overflow{}-> {}", currentPath, obj); Console.log("Overflow{}-> {}", key.watchable(), obj);
} }
}; };

View File

@ -14,18 +14,18 @@ package org.dromara.hutool.setting;
import org.dromara.hutool.core.collection.ListUtil; import org.dromara.hutool.core.collection.ListUtil;
import org.dromara.hutool.core.convert.Convert; import org.dromara.hutool.core.convert.Convert;
import org.dromara.hutool.core.io.file.FileUtil;
import org.dromara.hutool.core.io.IoUtil;
import org.dromara.hutool.core.io.resource.Resource;
import org.dromara.hutool.core.io.resource.ResourceUtil;
import org.dromara.hutool.core.io.watch.watchers.SimpleWatcher;
import org.dromara.hutool.core.io.watch.WatchMonitor;
import org.dromara.hutool.core.io.watch.WatchUtil;
import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.func.LambdaUtil; import org.dromara.hutool.core.func.LambdaUtil;
import org.dromara.hutool.core.func.SerSupplier; import org.dromara.hutool.core.func.SerSupplier;
import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.io.IoUtil;
import org.dromara.hutool.core.io.file.FileUtil;
import org.dromara.hutool.core.io.resource.Resource;
import org.dromara.hutool.core.io.resource.ResourceUtil;
import org.dromara.hutool.core.io.watch.WatchMonitor;
import org.dromara.hutool.core.io.watch.WatchUtil;
import org.dromara.hutool.core.io.watch.watchers.SimpleWatcher;
import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.text.CharUtil; import org.dromara.hutool.core.text.CharUtil;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.util.CharsetUtil; import org.dromara.hutool.core.util.CharsetUtil;
import org.dromara.hutool.log.LogUtil; import org.dromara.hutool.log.LogUtil;
import org.dromara.hutool.setting.props.Props; import org.dromara.hutool.setting.props.Props;
@ -33,15 +33,9 @@ import org.dromara.hutool.setting.props.Props;
import java.io.File; import java.io.File;
import java.net.URL; import java.net.URL;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.WatchEvent; import java.nio.file.WatchEvent;
import java.util.Arrays; import java.nio.file.WatchKey;
import java.util.Collection; import java.util.*;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.function.Consumer; import java.util.function.Consumer;
/** /**
@ -217,13 +211,11 @@ public class Setting extends AbsSetting implements Map<String, String> {
public void autoLoad(final boolean autoReload, final Consumer<Boolean> callback) { public void autoLoad(final boolean autoReload, final Consumer<Boolean> callback) {
if (autoReload) { if (autoReload) {
Assert.notNull(this.resource, "Setting resource must be not null !"); Assert.notNull(this.resource, "Setting resource must be not null !");
if (null != this.watchMonitor) { // 先关闭之前的监听
// 先关闭之前的监听 IoUtil.closeQuietly(this.watchMonitor);
this.watchMonitor.close();
}
this.watchMonitor = WatchUtil.createModify(resource.getUrl(), new SimpleWatcher() { this.watchMonitor = WatchUtil.createModify(resource.getUrl(), new SimpleWatcher() {
@Override @Override
public void onModify(final WatchEvent<?> event, final Path currentPath) { public void onModify(final WatchEvent<?> event, final WatchKey key) {
final boolean success = load(); final boolean success = load();
// 如果有回调加载完毕则执行回调 // 如果有回调加载完毕则执行回调
if (callback != null) { if (callback != null) {

View File

@ -22,9 +22,9 @@ import org.dromara.hutool.core.io.IoUtil;
import org.dromara.hutool.core.io.file.FileUtil; import org.dromara.hutool.core.io.file.FileUtil;
import org.dromara.hutool.core.io.resource.Resource; import org.dromara.hutool.core.io.resource.Resource;
import org.dromara.hutool.core.io.resource.ResourceUtil; import org.dromara.hutool.core.io.resource.ResourceUtil;
import org.dromara.hutool.core.io.watch.watchers.SimpleWatcher;
import org.dromara.hutool.core.io.watch.WatchMonitor; import org.dromara.hutool.core.io.watch.WatchMonitor;
import org.dromara.hutool.core.io.watch.WatchUtil; import org.dromara.hutool.core.io.watch.WatchUtil;
import org.dromara.hutool.core.io.watch.watchers.SimpleWatcher;
import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.lang.getter.TypeGetter; import org.dromara.hutool.core.lang.getter.TypeGetter;
import org.dromara.hutool.core.map.MapUtil; import org.dromara.hutool.core.map.MapUtil;
@ -39,8 +39,8 @@ import java.io.IOException;
import java.io.Writer; import java.io.Writer;
import java.net.URL; import java.net.URL;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.WatchEvent; import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.util.Arrays; import java.util.Arrays;
import java.util.Properties; import java.util.Properties;
@ -234,7 +234,7 @@ public final class Props extends Properties implements TypeGetter<CharSequence>
} }
this.watchMonitor = WatchUtil.createModify(this.resource.getUrl(), new SimpleWatcher() { this.watchMonitor = WatchUtil.createModify(this.resource.getUrl(), new SimpleWatcher() {
@Override @Override
public void onModify(final WatchEvent<?> event, final Path currentPath) { public void onModify(final WatchEvent<?> event, final WatchKey key) {
load(); load();
} }
}); });