package bluechip.jnotify;
import java.io.File;
import java.util.HashMap;
import net.contentobjects.jnotify.JNotify;
import net.contentobjects.jnotify.JNotifyException;
import net.contentobjects.jnotify.JNotifyListener;
public class FileMonitor {
private final HashMap<File, FileMonitorConfig> configs;
private JNotifyListener listener;
private boolean running;
private final Object waiter = new Object();
private long minWatchedInterval = 100;
private File lastWatchedFile;
private long lastWatchedTime;
public FileMonitor() {
configs = new HashMap<File, FileMonitorConfig>();
listener = new JNotifyListener() {
public void fileRenamed(int wd, String parent, String oldName, String newName) {
if (accept(parent, oldName, newName)) {
renamed(parent, oldName, newName);
}
}
public void fileModified(int wd, String parent, String name) {
if (accept(parent, name)) {
modified(parent, name);
}
}
public void fileDeleted(int wd, String parent, String name) {
if (accept(parent, name)) {
deleted(parent, name);
}
}
public void fileCreated(int wd, String parent, String name) {
if (accept(parent, name)) {
created(parent, name);
}
}
};
}
public boolean addWatch(FileMonitorConfig config) {
configs.put(config.getFile(), config);
try {
config.watchId = (JNotify.addWatch(config.getPath(), config.getMask(), config
.isWatchSubtree(), listener));
} catch (JNotifyException e) {
return false;
}
return true;
}
private boolean accept(String parent, String name) {
File file = new File(parent, name);
if (file.equals(lastWatchedFile)
&& System.currentTimeMillis() - lastWatchedTime < minWatchedInterval) {
return false;
}
FileMonitorConfig config = configs.get(file);
if (config == null) {
config = configs.get(new File(parent));
}
if (config != null && config.accept(file)) {
lastWatchedFile = file;
lastWatchedTime = System.currentTimeMillis();
return true;
} else
return false;
}
private boolean accept(String parent, String oldName, String newName) {
File file = new File(parent, oldName);
FileMonitorConfig config = configs.get(file);
boolean isFile = true;
if (config == null) {
config = configs.get(new File(parent));
isFile = false;
}
if (config != null && config.accept(file)) {
lastWatchedFile = new File(parent, newName);
if (isFile) {
configs.remove(file);
config.file = lastWatchedFile;
configs.put(lastWatchedFile, config);
}
lastWatchedTime = System.currentTimeMillis();
return true;
} else
return false;
}
public void start() throws JNotifyException {
running = true;
Thread t = new Thread() {
public void run() {
while (running) {
synchronized (waiter) {
try {
waiter.wait();
} catch (InterruptedException e) {
}
}
}
}
};
t.setDaemon(true);
t.start();
}
public void stop() {
running = false;
synchronized (waiter) {
waiter.notify();
}
}
public boolean removeWatch(File file) {
FileMonitorConfig config = configs.remove(file);
if (config == null)
return false;
try {
JNotify.removeWatch(config.watchId);
} catch (JNotifyException e) {
return false;
}
return true;
}
protected void renamed(String parent, String oldName, String newName) {
}
protected void modified(String parent, String name) {
}
protected void deleted(String parent, String name) {
}
protected void created(String parent, String name) {
}
/**
* @return the minWatchedInterval
*/
public long getMinWatchedInterval() {
return minWatchedInterval;
}
/**
* @param minWatchedInterval
* the minWatchedInterval to set
*/
public void setMinWatchedInterval(long minWatchedInterval) {
this.minWatchedInterval = minWatchedInterval;
}
/**
* @return the lastWatchedFile
*/
public File getLastWatchedFile() {
return lastWatchedFile;
}
/**
* @return the lastWatchedTime
*/
public long getLastWatchedTime() {
return lastWatchedTime;
}
}
以下方法由子类实现:
引用
protected void renamed(String parent, String oldName, String newName) {
}
protected void modified(String parent, String name) {
}
protected void deleted(String parent, String name) {
}
protected void created(String parent, String name) {
}
package bluechip.jnotify;
import java.io.File;
import java.io.FileFilter;
import net.contentobjects.jnotify.JNotify;
public final class FileMonitorConfig {
public enum MASK {
/**
* A file created
*/
CREATED(JNotify.FILE_CREATED),
/**
* A file deleted
*/
DELETED(JNotify.FILE_DELETED),
/**
* A file modified
*/
MODIFIED(JNotify.FILE_MODIFIED),
/**
* A file renamed
*/
RENAMED(JNotify.FILE_RENAMED);
private final int mask;
private MASK(int mask) {
this.mask = mask;
}
/**
* @return the mask
*/
public int getMask() {
return mask;
}
}
final String path;
final boolean watchSubtree;
int mask;
FileFilter filter;
int watchId;
File file;
public FileMonitorConfig(String filename, MASK... masks) {
file = new File(filename);
if (!file.isFile()) {
throw new IllegalArgumentException("Not a file: " + filename);
}
this.filter = new FileFilter() {
public boolean accept(File file1) {
return file.equals(file1);
}
};
this.path = file.getParent();
this.watchSubtree = false;
if (masks == null || masks.length == 0) {
this.mask = JNotify.FILE_ANY;
} else {
for (MASK m : masks) {
mask |= m.getMask();
}
}
}
public FileMonitorConfig(String path, boolean watchSubtree, MASK... masks) {
file = new File(path);
if (!file.isDirectory())
throw new IllegalArgumentException("Not a directory: " + path);
this.path = path;
this.watchSubtree = watchSubtree;
if (masks == null || masks.length == 0) {
this.mask = JNotify.FILE_ANY;
} else {
for (MASK m : masks) {
mask |= m.getMask();
}
}
}
/**
* @return the filter
*/
public FileFilter getFilter() {
return filter;
}
/**
* Tests whether or not the specified abstract pathname should be monitored.
*
* @param pathname
* @return
* @see java.io.FileFilter#accept(java.io.File)
*/
public boolean accept(File pathname) {
return filter == null ? true : filter.accept(pathname);
}
/**
* @param filter
* the filter to set
*/
public void setFilter(FileFilter filter) {
if (file.isFile())
throw new UnsupportedOperationException("It is a file,set filter for a directory.");
this.filter = filter;
}
/**
* @return the mask
*/
public int getMask() {
return mask;
}
/**
* @return the path
*/
public String getPath() {
return path;
}
/**
* @return the watchSubtree
*/
public boolean isWatchSubtree() {
return watchSubtree;
}
/**
* @return the file
*/
public File getFile() {
return file;
}
}