目录监控

  • 增加maven依赖
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.5</version>
        </dependency>
  • 编写listener
public class FileListener extends FileAlterationListenerAdaptor {
    @Override
    public void onDirectoryCreate(File directory) {
        super.onDirectoryCreate(directory);
    }

    @Override
    public void onDirectoryChange(File directory) {
        super.onDirectoryChange(directory);
    }

    @Override
    public void onDirectoryDelete(File directory) {
        super.onDirectoryDelete(directory);
    }

    @Override
    public void onFileDelete(File file) {
        super.onFileDelete(file);
    }

    // ......省略其他

}
  • 编写monitor
public interface IFileMonitor {
    void startMonitor();
    void stopMonitor();

    void setListener(FileListener listener);
}
public class FileMonitor implements IFileMonitor {
    private FileAlterationMonitor monitor;
    private FileAlterationObserver observer;

    private FileListener listener;

    // seconds
    private long time;
    private String path;

    public FileMonitor(int seconds, String path){
        this.time = seconds;
        this.path = path;
    }

    public void setListener(FileListener listener){
        this.listener = listener;
    }

    public void startMonitor(){
        observer = new FileAlterationObserver(path);
        observer.addListener(listener);

        monitor = new FileAlterationMonitor(TimeUnit.SECONDS.toMillis(time));
        monitor.addObserver(observer);

        try {
            monitor.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void stopMonitor(){
        try {
            monitor.stop();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 其他
    其中关闭monitor需要调用stop方法, 查看源码如下。
    默认使用interval设置join时间,并传递中断信号。
    使用变量running控制线程退出。
  public synchronized void stop() throws Exception {
        this.stop(this.interval);
    }

    public synchronized void stop(long stopInterval) throws Exception {
        if(!this.running) {
            throw new IllegalStateException("Monitor is not running");
        } else {
            this.running = false;

            try {
                this.thread.join(stopInterval);
            } catch (InterruptedException var5) {
                Thread.currentThread().interrupt();
            }

            Iterator i$ = this.observers.iterator();

            while(i$.hasNext()) {
                FileAlterationObserver observer = (FileAlterationObserver)i$.next();
                observer.destroy();
            }

        }
    }
  • 其他注意点
    在同一个monitor周期中,如果快速的删除和恢复同样的文件(属性没有任何变化),并不会触发事件调用。
在MFC中实现 EventSink 。 (1) 在MFC中,添加ATL简单对象 CFileMonitorSink (2) 添加继承父类 IDispEventImpl public IDispEventImpl (1) 0 唯一标识符, 用于区别 连接到 事件源的多个客户端 CFileMonitorSink, 当前类名 _IFun1Events, COM 中的事件源接口, 包含各种事件 __ATLEventLib, COM 中Lib类 具体查 MSDN --IDispEventImpl (2) 添加映射项 BEGIN_SINK_MAP(CFileMonitorSink) SINK_ENTRY_EX( 0, __uuidof(_IFun1Events), 1, OnNotify) //0 唯一标识符,用于区别 连接到 事件源的多个客户端 同上 , 1, 事件号 , 发生1号事件 由OnNotify来处理 SINK_ENTRY_EX( 0, __uuidof(_IFun1Events), 2, OnNotify2) //发生2号事件 由OnNotify2来处理 END_SINK_MAP() 并添加方法 STDMETHOD(OnNotify)(void); //事件处理类 STDMETHOD(OnNotify2)(CHAR* lszContent); (3) 连接到COM中的事件容器 添加变量 CComPtr m_Object; //COM 中的事件源对象 添加方法 STDMETHOD(Start)(IUnknown* pSinkThisObject, VARIANT_BOOL* succeeded) { AFX_MANAGE_STATE(AfxGetAppModuleState()); // TODO: 在此添加实现代码 if ( DispEventAdvise(pSinkThisObject) == S_OK ) { m_Object = pSinkThisObject; *succeeded = VARIANT_TRUE; } else { *succeeded = VARIANT_FALSE; } return S_OK; } STDMETHOD(Stop)(void) //解除连接 { AFX_MANAGE_STATE(AfxGetAppModuleState()); DispEventUnadvise(m_Object); return S_OK; } 在其他类中的 使用方法: CComPtr m_FileMonitorSink; CComPtr m_FileMonitor; //COM中导出接口 CoInitialize(0); HRESULT lRt = m_FileMonitorSink.CoCreateInstance( __uuidof(FileMonitorSink) ); lRt = m_FileMonitor.CoCreateInstance(__uuidof(Fun1)); //创建COM接口实例 VARIANT_BOOL succeeded; lRt = m_FileMonitorSink->Start(m_FileMonitor, &succeeded); //把 m_FileMonitorSink 连接到COM中的事件容器上 m_FileMonitor->HelloWorld(); //调用COM接口,接口中触发事件s m_FileMonitorSink->stop(); //从COM接口中解除连接 CoUninitialize(); // ################# CFileMonitorSink 类代码 ################# class ATL_NO_VTABLE CFileMonitorSink : public CComObjectRootEx, public CComCoClass, public IDispatchImpl, public IDispEventImpl { public: CFileMonitorSink() { } DECLARE_REGISTRY_RESOURCEID(IDR_FILEMONITORSINK) BEGIN_COM_MAP(CFileMonitorSink) COM_INTERFACE_ENTRY(IFileMonitorSink) COM_INTERFACE_ENTRY(IDispatch) END_COM_MAP() BEGIN_SINK_MAP(CFileMonitorSink) SINK_ENTRY_EX( 0, __uuidof(_IFun1Events), 1, OnNotify) SINK_ENTRY_EX( 0, __uuidof(_IFun1Events), 2, OnNotify2) END_SINK_MAP() DECLARE_PROTECT_FINAL_CONSTRUCT() HRESULT FinalConstruct() { return S_OK; } void FinalRelease() { } CComPtr m_Object; //COM 事件源对象 public: STDMETHOD(OnNotify)(void); STDMETHOD(Stop)(void); STDMETHOD(Start)(IUnknown* pSinkThisObject, VARIANT_BOOL* succeeded); STDMETHOD(OnNotify2)(CHAR* lszContent); };
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值