这一片博客将介绍通过JAVA实现监听文件的变更,提供一种解决方案。
文件改变接口
import java.io.File;
public interface FileMonitorListener
{
void fileChanged(File file);
}
文件监听类
import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Timer;
import java.util.TimerTask;
/**
* 文件监听
*
* @author jianggujin
*
*/
public class FileMonitor
{
/** 定时器 **/
private Timer timer;
/** 监听的文件 **/
private HashMap<File, Long> monitorFiles;
/** 监听器,采用弱引用,避免影响垃圾回收 **/
private Collection<WeakReference<FileMonitorListener>> listeners;
/**
* 构造方法,默认1秒监控一次
*/
public FileMonitor()
{
this(1000);
}
/**
* 构造方法
*
* @param pollingInterval
* 监听时间间隔
*/
public FileMonitor(long pollingInterval)
{
monitorFiles = new HashMap<File, Long>();
listeners = new ArrayList<WeakReference<FileMonitorListener>>();
timer = new Timer(true);
timer.schedule(new FileMonitorNotifier(), 0, pollingInterval);
}
/**
* 停止监听
*/
public void stop()
{
timer.cancel();
}
/**
* 添加监听文件
*
* @param file
*/
public void addFile(File file)
{
if (!monitorFiles.containsKey(file))
{
long modifiedTime = file.exists() ? file.lastModified() : -1;
monitorFiles.put(file, new Long(modifiedTime));
}
}
/**
* 移除监听文件
*
* @param file
*/
public void removeFile(File file)
{
monitorFiles.remove(file);
}
/**
* 添加监听器
*
* @param fileListener
*/
public void addListener(FileMonitorListener fileListener)
{
// 判断监听器是否已存在
for (Iterator<WeakReference<FileMonitorListener>> iterator = listeners
.iterator(); iterator.hasNext();)
{
if (iterator.next().get() == fileListener)
{
return;
}
}
// 以弱引用的方式添加监听器
listeners.add(new WeakReference<FileMonitorListener>(fileListener));
}
/**
* 移除监听器
*
* @param fileListener
*/
public void removeListener(FileMonitorListener fileListener)
{
for (Iterator<WeakReference<FileMonitorListener>> iterator = listeners
.iterator(); iterator.hasNext();)
{
if (iterator.next().get() == fileListener)
{
iterator.remove();
break;
}
}
}
/**
* 文件监听通知任务
*
* @author jianggujin
*
*/
private class FileMonitorNotifier extends TimerTask
{
public void run()
{
// 获得文件列表
Collection<File> files = new ArrayList<File>(monitorFiles.keySet());
// 遍历
for (Iterator<File> iterator = files.iterator(); iterator.hasNext();)
{
File file = iterator.next();
long lastModifiedTime = monitorFiles.get(file).longValue();
long newModifiedTime = file.exists() ? file.lastModified() : -1;
// 最后修改时间不同,认为文件修改
if (newModifiedTime != lastModifiedTime)
{
// 修改原信息
monitorFiles.put(file, newModifiedTime);
// 遍历监听器
for (Iterator<WeakReference<FileMonitorListener>> iterator2 = listeners
.iterator(); iterator2.hasNext();)
{
WeakReference<FileMonitorListener> reference = iterator2
.next();
FileMonitorListener listener = (FileMonitorListener) reference
.get();
// 如果监听器已经被垃圾回收,则此时监听器为null
if (listener == null)
{
iterator2.remove();
}
else
{
listener.fileChanged(file);
}
}
}
}
}
}
public static void main(String[] args)
{
FileMonitor monitor = new FileMonitor();
monitor.addFile(new File("test.txt"));
monitor.addListener(new FileMonitorListener()
{
public void fileChanged(File file)
{
System.out.println(file.getName() + " changed!");
}
});
// 启动一个线程,防止程序退出
new Thread()
{
public void run()
{
while (true)
{
}
};
}.start();
}
}
在JDK1.7中,JAVA提供了监听文件的方法,参考示例如下:
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKind;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.List;
public class Main {
public static void main(String[] args) {
Path myDir = Paths.get("test.txt");
try {
WatchService watcher = myDir.getFileSystem().newWatchService();
myDir.register(watcher, StandardWatchEventKind.ENTRY_CREATE,
StandardWatchEventKind.ENTRY_DELETE, StandardWatchEventKind.ENTRY_MODIFY);
WatchKey watckKey = watcher.take();
List<WatchEvent<?>> events = watckKey.pollEvents();
for (WatchEvent event : events) {
if (event.kind() == StandardWatchEventKind.ENTRY_CREATE) {
System.out.println("Created: " + event.context().toString());
}
if (event.kind() == StandardWatchEventKind.ENTRY_DELETE) {
System.out.println("Delete: " + event.context().toString());
}
if (event.kind() == StandardWatchEventKind.ENTRY_MODIFY) {
System.out.println("Modify: " + event.context().toString());
}
}
} catch (Exception e) {
System.out.println("Error: " + e.toString());
}
}
}