`
wangxucumt
  • 浏览: 26004 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java文件监控方式(转载)

    博客分类:
  • Java
 
阅读更多
有三种方式:
1、java common.io    内部实现是遍历的方式,小文件夹的效率还好,比如我测试60G的目录,就很慢很慢了。
2、jdk 7 的watch service    //没有测试
3、jnotify                   直接调用windows的api,效率很高,也很简单,推荐使用。

------------------------------------------------------------------------------------------------------------------------------------------------------------
common.io
需要java.io 2.1及其以上版本。版本地址如下:
http://commons.apache.org/io/download_io.cgi

import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
 
/** 
* 自定义文件监听器 
* @author   
* @date    2010-11-16 
* @file    org.demo.file.MyFileListener.java 
*/ 
public class MyFileListener extends FileAlterationListenerAdaptor{  
    @Override 
    public void onFileCreate(File file) {  
        System.out.println("[新建]:" + file.getAbsolutePath());  
    }  
    @Override 
    public void onFileChange(File file) {  
        System.out.println("[修改]:" + file.getAbsolutePath());  
    }  
    @Override 
    public void onFileDelete(File file) {  
        System.out.println("[删除]:" + file.getAbsolutePath());  
    }  
}


import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;


public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) throws Exception{
           // 监控目录  
        String rootDir = "d:\\Temp";  
        // 轮询间隔 5 毫秒  
        long interval = 5l;  
        //   
        FileAlterationObserver observer = new FileAlterationObserver(  
                                              rootDir,null,   
                                              null);  
        observer.addListener(new MyFileListener());  
        FileAlterationMonitor monitor = new FileAlterationMonitor(interval,observer);  
        // 开始监控  
        monitor.start(); 
    }
}
------------------------------------------------------------------------------------------------------------------------------------------------------------
jdk7 watchservice
详见 http://www.cnblogs.com/callwangxiang/archive/2011/08/04/JavaDirectoryWatcherFileWatcher.html
Java SE 7 Tutorial中增加了一个监控目录变更情况的示例,用于介绍其新发布的WatchService API。



但对于用惯了.NET FileWatcher的用户而言,如果用于项目我认为它有两个欠缺:

1、应该提供一个独立线程后台运行机制,让这个监控过程自己在后台转,不影响前端处理

2、 Java不像.NET有内置的源生事件机制,不过可以借助它内置的Observer/Observable对象用观察者模式实现准事件



下面是把Java SE Tutorial示例中无关内容删除,补充上述两个扩展后的实现,因为这个API比较新,也希望能和大家多多探讨:



1、参考.NET定义事件参数对象

package marvellousworks.practicalpattern.concept.unittest;

import java.nio.file.WatchEvent.Kind;

/**
* 文件系统事件类型
* @author wangxiang
*
*/
public final class FileSystemEventArgs {
    private final String fileName;
    private final Kind<?> kind;
   
    public FileSystemEventArgs(String fileName, Kind<?> kind){
        this.fileName = fileName;
        this.kind = kind;
    }
   
    /**
     * 文件的路径
     */
    public String getFileName(){return fileName;}
   
    /**
     * 操作类型:变更、创建、删除
     */
    @SuppressWarnings("rawtypes")
    public Kind getKind(){return kind;}
}


2、定义DirectoryWatcher,用于监控某个文件夹,至于如何扩展FileWatcher则可以在这个基础上通过限定文件名称和操作类型的方式扩展



package marvellousworks.practicalpattern.concept.unittest;

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.WatchEvent;
import java.nio.file.WatchEvent.Kind;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.Observable;
import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

import static java.nio.file.StandardWatchEventKinds.*;

/**
* 监控一个目录内文件的更新、创建和删除事件(不包括子目录)
*
* 对于http://download.oracle.com/javase/tutorial/essential/io/notification.html进行了改造
* 使其更接近.NET的DirectoryWatcher使用习惯
*
* 由于java没有类似.NET源生的事件机制
* 因此实现上采用了Java SE自带的Observer/Observable对象对外抛出“假”事件
*
* 适于Java SE 7
*
* @author wangxiang
*
*/
public class DirectoryWatcher extends Observable{

    private WatchService watcher;
    private Path path;
    private WatchKey key;
    private Executor executor = Executors.newSingleThreadExecutor();
   
    FutureTask<Integer> task = new FutureTask<Integer>(
            new Callable<Integer>(){
                public Integer call() throws InterruptedException{
                    processEvents();
                    return Integer.valueOf(0);}});

    @SuppressWarnings("unchecked")
    static <T> WatchEvent<T> cast(WatchEvent<?> event) {
        return (WatchEvent<T>) event;
    }

    public DirectoryWatcher(String dir) throws IOException {
        watcher = FileSystems.getDefault().newWatchService();
        path = Paths.get(dir);
        //    监控目录内文件的更新、创建和删除事件
        key = path.register(watcher, ENTRY_MODIFY, ENTRY_CREATE, ENTRY_DELETE);
    }

    /**
     * 启动监控过程
     */
    public void execute(){
        // 通过线程池启动一个额外的线程加载Watching过程
        executor.execute(task);       
    }
   
    /**
     * 关闭后的对象无法重新启动
     * @throws IOException
     */
    public void shutdown() throws IOException {
        watcher.close();
        executor = null;
    }

    /**
     * 监控文件系统事件
     */
    void processEvents() {
        while (true) {
            // 等待直到获得事件信号
            WatchKey signal;
            try {
                signal = watcher.take();
            } catch (InterruptedException x) {
                return;
            }

            for (WatchEvent<?> event : signal.pollEvents()) {
                Kind<?> kind = event.kind();

                // TBD - provide example of how OVERFLOW event is handled
                if (kind == OVERFLOW) {
                    continue;
                }

                // Context for directory entry event is the file name of entry
                WatchEvent<Path> ev = cast(event);
                Path name = ev.context();
                notifiy(name.getFileName().toString(), kind);
            }
            //    为监控下一个通知做准备
            key.reset();
        }
    }
   
    /**
     * 通知外部各个Observer目录有新的事件更新
     */
    void notifiy(String fileName, Kind<?> kind){
        // 标注目录已经被做了更改
        setChanged();
        //     主动通知各个观察者目标对象状态的变更
        //    这里采用的是观察者模式的“推”方式
        notifyObservers(new FileSystemEventArgs(fileName, kind));
    }
}


3、单元测试

package marvellousworks.practicalpattern.concept.unittest;

import static org.junit.Assert.*;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

import org.junit.Test;
import static java.nio.file.StandardWatchEventKinds.*;

public class DirectoryWatcherFixture {

    private static final String DIR_PATH =System.getProperty("user.dir");
    private static final File DIR = new File(DIR_PATH);
    private static final String SUFFIX = ".txt";
    private static final String PREFIX = "test";
    private static final int ADD_TIMES = 3;

    /**
     * 观察者
     * @author wangxiang
     *
     */
    public class Logger implements Observer{
        @Override
        public void update(Observable observable, Object eventArgs) {
            FileSystemEventArgs args = (FileSystemEventArgs) eventArgs;
            System.out.printf("%s has been %s\n", args.getFileName(), args.getKind());
            assertTrue(args.getFileName().startsWith(PREFIX));
                assertEquals(ENTRY_CREATE, args.getKind());
        }
    }
   
    @Test
    public void testWatchFile() throws IOException, InterruptedException{
        DirectoryWatcher watcher = new DirectoryWatcher(DIR_PATH);
        Logger l1 = new Logger();
        watcher.addObserver(l1);
        watcher.execute();
       
        //    创建一系列临时文件
        List<String> files = new ArrayList<>();
        for(int i=0; i<ADD_TIMES; i++){
            files.add(File.createTempFile(PREFIX, SUFFIX, DIR).toString());
        }
       
        //    延迟等待后台任务的执行
        Thread.sleep(4000);
        watcher.shutdown();
        System.out.println("finished");
    }
}


Console窗口显示的测试内容



test5769907807190550725.txt has been ENTRY_CREATE
test4657672246246330348.txt has been ENTRY_CREATE
test1823102943601166149.txt has been ENTRY_CREATE
finished

------------------------------------------------------------------------------------------------------------------------------------------------------------
jnotify
详见 http://www.blogjava.net/pengo/archive/2011/01/09/342622.html
jnotify分为64位 和 32位。 详见 http://jnotify.sourceforge.net/
public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) throws Exception{
           // 监控目录  
        String rootDir = "Z:\\";
        String path = rootDir;
        int mask = JNotify.FILE_CREATED | JNotify.FILE_DELETED
                | JNotify.FILE_MODIFIED | JNotify.FILE_RENAMED;
        boolean watchSubtree = true;
        while (true) { //否则一次就完了
            System.out.println("begin watch");
            JNotify.addWatch(path, mask, watchSubtree, new MyJnotifyListner());
            Thread.sleep(10000);
            System.out.println("end watch");
        }
    }

}



import net.contentobjects.jnotify.JNotifyListener;


public class MyJnotifyListner implements JNotifyListener {
    public void fileRenamed(int wd, String rootPath, String oldName,
            String newName) {
        System.out.println("文件:" + rootPath + " : " + oldName + " 重命名为: "
                + newName + "\n");
    }

    public void fileModified(int wd, String rootPath, String name) {
        System.out.println("文件修改 " + rootPath + " : " + name + "\n");
    }

    public void fileDeleted(int wd, String rootPath, String name) {
        System.out.println("删除文件: " + rootPath + " : " + name + "\n");
    }

    public void fileCreated(int wd, String rootPath, String name) {
        System.out.println("新建文件: " + rootPath + " : " + name + "\n");
    }
}


分享到:
评论

相关推荐

    java文件监控例子

    文件监控例子http://www.blogjava.net/pengo/archive/2011/01/09/342622.html的附件源码

    JAVA文件监控(源码)

    通过commons-io监测文件。可检查目录的文件新建、修改、删除等变化。 // 监控目录 String rootDir = "c:\\Downloads"; // 轮询间隔 10 秒 long interval = TimeUnit.SECONDS.toMillis(10); //文件格式 IOFileFilter ...

    java编写的ftp文件实时监控下载上传

    用java语言编写的ftp小工具,可以按指定时间监控ftp服务器,把服务器指定目录内新产生的文件或者文件夹下载到本地指定文件夹,下载后删除数据。 也可以监控本地文件夹,把文件夹内新产生的文件或者文件夹整体上传到...

    Java实现实时监控目录下文件变化的方法

    今天小编就为大家分享一篇关于Java实现实时监控目录下文件变化的方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

    java实现简单远程监控

    java实现远程监控

    Java 文件监控,实时监控文件加载

    NULL 博文链接:https://sziitjiang.iteye.com/blog/1701660

    java实现文件监控小工具

    java实现的文件监控小工具,监控文件,新增,修改,删除,重命名。 用于代码审计时监控文件夹内文件的变动,支持Mac,Windows,Linux。 第一次运行时请根据提示在此页面下载对应动态依赖库放到指定位置即可(注意...

    java实现windows文件系统操作监控

    java实现的一个监控windows文件夹中的文件的增删改等操作,根据不同的需要修改代码,可以做成不同的功能,如文件检索,文件保护,文件自动加密等程序应用

    文件监控文件监控文件监控文件监控

    可以简单的监控你的文件不被移动、修改和删除,用java实现,没有使用JNI的方式去调用,所以只是模拟了文件的监控,还有很多的确定..

    java实现,简单文件监控

    对本地文件实施的简单监控,如不能移动,不能复制和粘贴,复制和粘贴时监控系统剪贴板的。

    java流量监控软件

    java 开发的基于交换机端口的流量监控软件,以图形界面显示出来。

    java实现自定义Weblogic监控

    java实现自定义Weblogic监控java实现自定义Weblogic监控java实现自定义Weblogic监控

    Java 服务器信息监控

    这是java做的服务器监控程序,支持多系统如window,Linux等主流系统,可监控物理内存,cpu,网络连接,服务等

    java写的ftp下载上传定时监控

    java写的ftp,下载上传文件,定时监控下载上传,自动解压加压,

    基于java的文件监控程序设计与实现.pdf

    基于java的文件监控程序设计与实现.pdf

    java实现文件监控.docx

    java实现文件监控

    java反编译工具(.class文件反编译成.java文件)

    java反编译工具(.class文件反编译成.java文件) 解压后点击exe文件打开工具,点击open菜单选择.class文件执行后即生成.java文件 一直在使用的,方便,系统维护必不可少

    zabbix监控JAVA 进程 JVM数据统计分析告警监控

    zabbix自动发现JAVA进程,并进行自动添加监控JAVA 进程的JVM数据,统计分析告警监控。...支持多种中间件,tomcat、weblogic、微服务方式部署JAVA应用监控。 自带发现脚本和监控脚本,以及zabbix导入模板。

    Java读取大文件的处理

    Java读取大文件的处理 Java读取大文件的处理是Java编程中的一项重要技术,特别是在处理大文件时需要注意性能和响应速度。下面我们将对Java读取大文件的处理技术进行详细的介绍。 标题解释 Java读取大文件的处理是...

    基于Java的Phoenix开源监控平台设计源码

    本项目是基于Java的Phoenix开源监控平台设计源码,共有1306个文件,包括815个Java文件、75个GIF图像文件等。Phoenix是一个灵活可配置的监控平台,能够监控应用程序、服务器、Docker、数据库、网络、TCP端口和HTTP...

Global site tag (gtag.js) - Google Analytics