实现功能:实时监控指定目录下文件的增加 / 更新 / 删除 情况.
// monitor.file.FileMonitor.java
package monitor.file;
/**
*@date 2010-3-18 上午10:12:14
*@author dycc
*@file monitor.file.FileMonitor.java
*/
public class FileMonitor {
public static void main(String[] args) {
FileSchedulerTask task = new FileSchedulerTask("D:\\Temp");
FileScheduler monitor = new FileScheduler();
monitor.schedule(task, new TimeStep());
}
}
// monitor.file.FileScheduler.java
package monitor.file;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
/**
*@date 2010-3-18 上午10:31:26
*@author dycc
*@file monitor.file.FileScheduler.java
*/
public class FileScheduler {
// 定时器
private final Timer timer;
public FileScheduler(){
timer = new Timer();
}
public FileScheduler(boolean isDaemon){
// 是否为守护线程
timer = new Timer(isDaemon);
}
/**
* 为定时器分配可执行任务
* @param task
* @param step
*/
public void schedule(Runnable task,TimeStep step){
Date time = step.next();
SchedulerTimerTask timeTask = new SchedulerTimerTask(task,step);
// 安排在指定的时间 time 执行指定的任务 timetask
timer.schedule(timeTask, time);
// 此处不使用
// public void schedule(TimerTask task, Date firstTime, long period)
// 执行定时任务,而是使用 reSchedule 来重复执行任务,是因为首次执行时可能需要做一些额外的初始化,
// 这样方便以后扩展.
}
/**
* 重新执行任务
* @param task
* @param step
*/
private void reSchedule(Runnable task,TimeStep step){
Date time = step.next();
SchedulerTimerTask timeTask = new SchedulerTimerTask(task,step);
// 安排在指定的时间 time 执行指定的任务 timetask
timer.schedule(timeTask, time);
}
/**
* 停止当前定时器
*/
public void cancle(){
timer.cancel();
}
/**
* 定时任务
* @author dycc
*
*/
private class SchedulerTimerTask extends TimerTask{
private Runnable task;
private TimeStep step;
public SchedulerTimerTask(Runnable task,TimeStep step){
this.task = task;
this.step = step;
}
@Override
public void run() {
// 执行指定任务
task.run();
// 继续重复执行任务
reSchedule(task, step);
}
}
}
// monitor.file.FileSchedulerTask.java
package monitor.file;
import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
*@date 2010-3-18 上午10:39:29
*@author dycc
*@file monitor.file.FileSchedulerTask.java
*/
public class FileSchedulerTask implements Runnable{
private boolean firstRun = true;
private String directory = "";
// 初始文件信息
private Map<String,Long> currentFiles = new HashMap<String,Long>();
// 当前文件信息
private Set<String> newFiles = new HashSet<String>();
/**
* 构造函数
*/
public FileSchedulerTask(){
}
public FileSchedulerTask(String directory){
this.directory = directory;
}
/**
* 在 run() 中执行具体任务
*/
public void run() {
File file = new File(directory);
if(firstRun){
firstRun = false;
// 初次运行
loadFileInfo(file);
System.out.println("----- init success -----");
} else{
// 检查文件更新状态[add,update]
checkFileUpdate(file);
// 检查被移除的文件[remove]
checkRemovedFiles();
// 清空临时文件集合
newFiles.clear();
}
}
/**
* 初始化文件信息
* @param file
*/
private void loadFileInfo(File file){
if(file.isFile()){
currentFiles.put(file.getAbsolutePath(), file.lastModified());
return;
}
File[] files = file.listFiles();
for(int i=0;i<files.length;i++){
loadFileInfo(files[i]);
}
}
/**
* 检查文件更新状态
* @param file
*/
private void checkFileUpdate(File file){
if(file.isFile()){
// 将当前文件加入到 newFiles 集合中
newFiles.add(file.getAbsolutePath());
//
Long lastModified = currentFiles.get(file.getAbsolutePath());
if(lastModified == null){
// 新加入文件
currentFiles.put(file.getAbsolutePath(), file.lastModified());
System.out.println("添加文件:" + file.getAbsolutePath());
return;
}
if(lastModified.doubleValue() != file.lastModified()){
// 更新文件
currentFiles.put(file.getAbsolutePath(), file.lastModified());
System.out.println("更新文件:" + file.getAbsolutePath());
return;
}
return;
} else if(file.isDirectory()){
File[] files = file.listFiles();
if(files == null || files.length == 0){
// 没有子文件或子目录时返回
return;
}
for(int i=0;i<files.length;i++){
checkFileUpdate(files[i]);
}
}
}
/**
* 检查被移除的文件
*/
private void checkRemovedFiles(){
// 增加或更新时,newFiles.size() == currentFiles.size()
// 删除时, newFiles.size() < currentFiles.size()
// 不可能出现 newFiles.size() > currentFiles.size()
if(newFiles.size() == currentFiles.size()){
// 增加或更新时没有被移除的文件,直接返回
return;
}
Iterator<String> it = currentFiles.keySet().iterator();
while(it.hasNext()){
String filename = it.next();
if(!newFiles.contains(filename)){
// 此处不能使用 currentFiles.remove(filename);从 map 中移除元素,
// 否则会引发同步问题.
// 正确的做法是使用 it.remove();来安全地移除元素.
it.remove();
System.out.println("删除文件:" + filename);
}
}
}
/**
* 起始目录
* @return
*/
public String getDirectory() {
return directory;
}
public void setDirectory(String directory) {
this.directory = directory;
}
}
// monitor.file.TimeStep.java
package monitor.file;
import java.util.Calendar;
import java.util.Date;
/**
*@date 2010-3-18 上午10:12:14
*@author dycc
*@file monitor.file.TimeStep.java
*/
public class TimeStep {
private Calendar calendar = Calendar.getInstance();
// calendar field
private int field = Calendar.SECOND;
// the amount of the date or time
private int amount = 10;
/**
* field
* @return
*/
public int getField() {
return field;
}
public void setField(int field) {
this.field = field;
}
/**
* amount
* @return
*/
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
/**
* 获取时间
* @exception IllegalArgumentException if field is unknown
* @return
*/
public Date next(){
calendar.add(field, amount);
return calendar.getTime();
}
}