分享

Java实现的文件监控管理

 LibraryPKU 2014-03-11

实现功能:实时监控指定目录下文件的增加 / 更新 / 删除 情况.

Java代码  收藏代码
  1. // monitor.file.FileMonitor.java  
  2. package monitor.file;  
  3.   
  4. /** 
  5.  *@date 2010-3-18 上午10:12:14 
  6.  *@author dycc 
  7.  *@file monitor.file.FileMonitor.java 
  8.  */  
  9. public class FileMonitor {  
  10.     public static void main(String[] args) {  
  11.         FileSchedulerTask task = new FileSchedulerTask("D:\\Temp");  
  12.         FileScheduler monitor = new FileScheduler();  
  13.         monitor.schedule(task, new TimeStep());  
  14.     }  
  15. }  
  16.   
  17. // monitor.file.FileScheduler.java  
  18. package monitor.file;  
  19.   
  20. import java.util.Date;  
  21. import java.util.Timer;  
  22. import java.util.TimerTask;  
  23.   
  24. /** 
  25.  *@date 2010-3-18 上午10:31:26 
  26.  *@author dycc 
  27.  *@file monitor.file.FileScheduler.java 
  28.  */  
  29. public class FileScheduler {  
  30.     // 定时器  
  31.     private final Timer timer;  
  32.       
  33.     public FileScheduler(){  
  34.         timer = new Timer();  
  35.     }  
  36.     public FileScheduler(boolean isDaemon){  
  37.         // 是否为守护线程  
  38.         timer = new Timer(isDaemon);  
  39.     }  
  40.     /** 
  41.      * 为定时器分配可执行任务 
  42.      * @param task 
  43.      * @param step 
  44.      */  
  45.     public void schedule(Runnable task,TimeStep step){  
  46.         Date time = step.next();  
  47.         SchedulerTimerTask timeTask = new SchedulerTimerTask(task,step);  
  48.         // 安排在指定的时间 time 执行指定的任务 timetask  
  49.         timer.schedule(timeTask, time);  
  50.         // 此处不使用  
  51.         // public void schedule(TimerTask task, Date firstTime, long period)  
  52.         // 执行定时任务,而是使用 reSchedule 来重复执行任务,是因为首次执行时可能需要做一些额外的初始化,  
  53.         // 这样方便以后扩展.  
  54.     }  
  55.     /** 
  56.      * 重新执行任务 
  57.      * @param task 
  58.      * @param step 
  59.      */  
  60.     private void reSchedule(Runnable task,TimeStep step){  
  61.         Date time = step.next();  
  62.         SchedulerTimerTask timeTask = new SchedulerTimerTask(task,step);  
  63.         // 安排在指定的时间 time 执行指定的任务 timetask  
  64.         timer.schedule(timeTask, time);  
  65.     }  
  66.     /** 
  67.      * 停止当前定时器 
  68.      */  
  69.     public void cancle(){  
  70.         timer.cancel();  
  71.     }  
  72.     /** 
  73.      * 定时任务 
  74.      * @author dycc 
  75.      * 
  76.      */  
  77.     private class SchedulerTimerTask extends TimerTask{  
  78.         private Runnable task;  
  79.         private TimeStep step;  
  80.           
  81.         public SchedulerTimerTask(Runnable task,TimeStep step){  
  82.             this.task = task;  
  83.             this.step = step;  
  84.         }  
  85.         @Override  
  86.         public void run() {  
  87.             // 执行指定任务  
  88.             task.run();  
  89.             // 继续重复执行任务  
  90.             reSchedule(task, step);  
  91.         }  
  92.     }  
  93. }  
  94.   
  95. // monitor.file.FileSchedulerTask.java  
  96. package monitor.file;  
  97.   
  98. import java.io.File;  
  99. import java.util.HashMap;  
  100. import java.util.HashSet;  
  101. import java.util.Iterator;  
  102. import java.util.Map;  
  103. import java.util.Set;  
  104.   
  105. /** 
  106.  *@date 2010-3-18 上午10:39:29 
  107.  *@author dycc 
  108.  *@file monitor.file.FileSchedulerTask.java 
  109.  */  
  110. public class FileSchedulerTask implements Runnable{  
  111.       
  112.     private boolean firstRun = true;  
  113.       
  114.     private String directory = "";  
  115.     // 初始文件信息  
  116.     private Map<String,Long> currentFiles = new HashMap<String,Long>();  
  117.     // 当前文件信息  
  118.     private Set<String> newFiles = new HashSet<String>();  
  119.       
  120.     /** 
  121.      * 构造函数 
  122.      */  
  123.     public FileSchedulerTask(){  
  124.           
  125.     }  
  126.     public FileSchedulerTask(String directory){  
  127.         this.directory = directory;  
  128.     }  
  129.     /** 
  130.      * 在 run() 中执行具体任务 
  131.      */  
  132.     public void run() {  
  133.         File file = new File(directory);  
  134.         if(firstRun){  
  135.             firstRun = false;  
  136.             // 初次运行  
  137.             loadFileInfo(file);  
  138.             System.out.println("----- init success -----");  
  139.         } else{  
  140.             // 检查文件更新状态[add,update]  
  141.             checkFileUpdate(file);  
  142.             // 检查被移除的文件[remove]  
  143.             checkRemovedFiles();  
  144.             // 清空临时文件集合  
  145.             newFiles.clear();  
  146.         }  
  147.     }  
  148.     /** 
  149.      * 初始化文件信息 
  150.      * @param file 
  151.      */  
  152.     private void loadFileInfo(File file){  
  153.         if(file.isFile()){  
  154.             currentFiles.put(file.getAbsolutePath(), file.lastModified());  
  155.             return;  
  156.         }  
  157.         File[] files = file.listFiles();  
  158.         for(int i=0;i<files.length;i++){  
  159.             loadFileInfo(files[i]);  
  160.         }  
  161.     }  
  162.     /** 
  163.      * 检查文件更新状态 
  164.      * @param file 
  165.      */  
  166.     private void checkFileUpdate(File file){  
  167.         if(file.isFile()){  
  168.             // 将当前文件加入到 newFiles 集合中  
  169.             newFiles.add(file.getAbsolutePath());  
  170.             //   
  171.             Long lastModified = currentFiles.get(file.getAbsolutePath());  
  172.             if(lastModified == null){  
  173.                 // 新加入文件  
  174.                 currentFiles.put(file.getAbsolutePath(), file.lastModified());  
  175.                 System.out.println("添加文件:" + file.getAbsolutePath());  
  176.                 return;  
  177.             }  
  178.             if(lastModified.doubleValue() != file.lastModified()){  
  179.                 // 更新文件  
  180.                 currentFiles.put(file.getAbsolutePath(), file.lastModified());  
  181.                 System.out.println("更新文件:" + file.getAbsolutePath());  
  182.                 return;  
  183.             }  
  184.             return;  
  185.         } else if(file.isDirectory()){  
  186.             File[] files = file.listFiles();  
  187.             if(files == null || files.length == 0){  
  188.                 // 没有子文件或子目录时返回  
  189.                 return;  
  190.             }  
  191.             for(int i=0;i<files.length;i++){  
  192.                 checkFileUpdate(files[i]);  
  193.             }  
  194.         }  
  195.     }  
  196.     /** 
  197.      * 检查被移除的文件 
  198.      */  
  199.     private void checkRemovedFiles(){  
  200.         // 增加或更新时,newFiles.size() == currentFiles.size()  
  201.         // 删除时,    newFiles.size()  < currentFiles.size()  
  202.         // 不可能出现      newFiles.size()  > currentFiles.size()  
  203.         if(newFiles.size() == currentFiles.size()){  
  204.             // 增加或更新时没有被移除的文件,直接返回  
  205.             return;  
  206.         }  
  207.         Iterator<String> it = currentFiles.keySet().iterator();  
  208.         while(it.hasNext()){  
  209.             String filename = it.next();  
  210.             if(!newFiles.contains(filename)){  
  211.                 // 此处不能使用 currentFiles.remove(filename);从 map 中移除元素,  
  212.                 // 否则会引发同步问题.  
  213.                 // 正确的做法是使用 it.remove();来安全地移除元素.  
  214.                 it.remove();  
  215.                 System.out.println("删除文件:" + filename);  
  216.             }  
  217.         }  
  218.     }  
  219.     /** 
  220.      * 起始目录 
  221.      * @return 
  222.      */  
  223.     public String getDirectory() {  
  224.         return directory;  
  225.     }  
  226.     public void setDirectory(String directory) {  
  227.         this.directory = directory;  
  228.     }  
  229. }  
  230.   
  231. // monitor.file.TimeStep.java  
  232. package monitor.file;  
  233.   
  234. import java.util.Calendar;  
  235. import java.util.Date;  
  236.   
  237. /** 
  238.  *@date 2010-3-18 上午10:12:14 
  239.  *@author dycc 
  240.  *@file monitor.file.TimeStep.java 
  241.  */  
  242. public class TimeStep {  
  243.     private Calendar calendar = Calendar.getInstance();  
  244.     // calendar field  
  245.     private int field = Calendar.SECOND;  
  246.     // the amount of the date or time  
  247.     private int amount = 10;  
  248.       
  249.     /** 
  250.      * field 
  251.      * @return 
  252.      */  
  253.     public int getField() {  
  254.         return field;  
  255.     }  
  256.     public void setField(int field) {  
  257.         this.field = field;  
  258.     }  
  259.     /** 
  260.      * amount 
  261.      * @return 
  262.      */  
  263.     public int getAmount() {  
  264.         return amount;  
  265.     }  
  266.     public void setAmount(int amount) {  
  267.         this.amount = amount;  
  268.     }  
  269.     /** 
  270.      * 获取时间 
  271.      * @exception IllegalArgumentException if field is unknown 
  272.      * @return 
  273.      */  
  274.     public Date next(){  
  275.         calendar.add(field, amount);  
  276.         return calendar.getTime();  
  277.     }  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多