WatchService API实现监听文件系统中的文件变化(包括各级子目录)

最近导师下发一个任务,要求实现监听文件系统中的文件变化,并实时向管理员报告,以便管理员及时做出相应的处理,以免造成不必要的损失。
网上搜索的了一下,发现使用WatchService来实现的比较多,WatchService是Java SE7增加的服务,位于java.nio.file包中。网上的朋友都只是实现了对某个指定目录的监视,不包括对其各级子目录的监视,这不符合我的要求,于是经过整理修改,实现了对目录及其各级子目录的监视,代码如下:

注:这里是对整个E盘进行监视,如果E盘的文件及其子目录很多的话,速度可能会比较慢。
【补充】:经过一段时间的项目经验,知道监控的方式主要分为两种:扫描式和事件驱动式,WatchService是采用扫描式的,所以比较慢。如果追求效率的话可以考虑使用apache的commons-io里面的FileAlteration,她是采用事件驱动式的,效率比较高。
下面是WatchService的代码:

package wds;

import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.nio.channels.*;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class WatchFile
{
    public static void main(String[] args) 
            throws Exception{

        String filePath = ("E:");

        // 获取文件系统的WatchService对象
        WatchService watchService = FileSystems.getDefault().newWatchService();
        Paths.get(filePath).register(watchService 
                , StandardWatchEventKinds.ENTRY_CREATE
                , StandardWatchEventKinds.ENTRY_MODIFY
                , StandardWatchEventKinds.ENTRY_DELETE);

        File file = new File(filePath);
        LinkedList fList = new LinkedList();
        fList.addLast(file);
        while (fList.size() > 0 ) {
            File f = fList.removeFirst();
            if(f.listFiles() == null)
                continue;
            for(File file2 : f.listFiles()){
                    if (file2.isDirectory()){//下一级目录
                    fList.addLast(file2);
                    //依次注册子目录
                    Paths.get(file2.getAbsolutePath()).register(watchService 
                            , StandardWatchEventKinds.ENTRY_CREATE
                            , StandardWatchEventKinds.ENTRY_MODIFY
                            , StandardWatchEventKinds.ENTRY_DELETE);
                }
            }
        }

        while(true)
        {
            // 获取下一个文件改动事件
            WatchKey key = watchService.take();
            for (WatchEvent event : key.pollEvents()) 
            {
                System.out.println(event.context() +" --> " + event.kind());
            }
            // 重设WatchKey
            boolean valid = key.reset();
            // 如果重设失败,退出监听
            if (!valid) 
            {
                break;
            }
        }
    }
}

你可能感兴趣的:(Java)