org.onetwo.common.watch.FileWatcher Maven / Gradle / Ivy
package org.onetwo.common.watch;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.onetwo.common.log.JFishLoggerFactory;
import org.onetwo.common.propconf.ResourceAdapter;
import org.onetwo.common.utils.Assert;
import org.onetwo.common.utils.list.JFishList;
import org.onetwo.common.utils.list.NoIndexIt;
import org.slf4j.Logger;
/********
* 用ScheduledThreadPoolExecutor实现,代替FileMonitor
* @author wayshall
*
*/
public class FileWatcher {
private static final int DEFAULT_INIT_DELAY = 3;
private static final int DEFAULT_THREAD_COUNT = 1;
public static final FileWatcher GLOBAL_WATCHER = newWatcher(DEFAULT_THREAD_COUNT);
public static FileWatcher newWatcher(int threadCount){
return new FileWatcher(threadCount, DEFAULT_INIT_DELAY);
}
private final Logger logger = JFishLoggerFactory.getLogger(this.getClass());
private final ScheduledExecutorService executor;
private int initDelay = DEFAULT_INIT_DELAY;
private FileWatcher(){
this(DEFAULT_THREAD_COUNT, DEFAULT_INIT_DELAY);
}
private FileWatcher(int threadCount, int initDelay){
executor = new ScheduledThreadPoolExecutor(threadCount);
this.initDelay = initDelay;
}
public void watchFile(FileChangeListener listener, ResourceAdapter>...files){
watchFile(1, listener, files);
}
public void watchFile(long periodSecond, FileChangeListener listener, ResourceAdapter>...files){
Assert.notEmpty(files);
WatchFileTask task = new WatchFileTask(files, listener);
addFileTask(periodSecond, task);
}
public void addFileTask(long periodSecond, WatchFileTask task){
logger.info(task.listFileString("\n watch file : "));
//固定延迟
executor.scheduleWithFixedDelay(task, initDelay, periodSecond, TimeUnit.SECONDS);
}
public static class WatchFileTask implements Runnable {
private final JFishList fileStates;
private final FileChangeListener listener;
private WatchFileTask(ResourceAdapter>[] files, FileChangeListener listener) {
super();
fileStates = JFishList.newList(files.length);
for(ResourceAdapter> file : files){
if(file.isSupportedToFile())
fileStates.add(new FileState(file));
}
this.listener = listener;
}
@Override
public void run() {
for(FileState state : fileStates){
if(state.isModified())
listener.fileChanged(state.file);
}
}
public String listFileString(final String beforeElement){
final StringBuilder str = new StringBuilder();
fileStates.each(new NoIndexIt() {
@Override
protected void doIt(FileState element) throws Exception {
str.append(beforeElement).append(element.file.getFile().getPath());
}
});
return str.toString();
}
}
private static class FileState {
private ResourceAdapter> file;
private long lastModified;
private FileState(ResourceAdapter> file) {
super();
this.file = file;
this.lastModified = file.getFile().lastModified();
}
public boolean isModified(){
long latestChange = this.file.getFile().lastModified();
if (this.lastModified != latestChange) {
this.lastModified = latestChange;
return true;
}
return false;
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy