美文网首页
监控目录变化

监控目录变化

作者: 良辰夜 | 来源:发表于2018-09-06 21:00 被阅读0次

    两种思路

    1. 建立一个线程,循环检测目录变化
    2. java7 提供了 WatchService ,专门应对这种需求。

    这里因为我们并不深入研究实现原理,仅做一个业务上实现,故选择第二种思路。

    1. 场景:

    1. 热部署
    2. 自定义场景: 其他程序将文件插到目录内,但不通知你。

    2. Path.register 的参数们:

    2.1 Modifier:

    这参数原先我不知道什么作用。
    后来在watchKey上面看到一个参数 watchSubtree,看名字居然是监控子树,:) 。

    watchKey.png

    然后我跟进,

    image.png

    最后终于看到这段代码。


    image.png

    原来是通过 ExtendedWatchEventModifier.FILE_TREE来设置的呀。
    我们经过测试后得出结论,该参数作用是代表监听目录及其子目录。

    注意:ExtendedWatchEventModifier.FILE_TREE仅能在window上用,linux没有此参数。

    2.2 WatchEvent.Kind

    这个参数,java7默认提供了一些枚举。
    StandardWatchEventKinds.ENTRY_CREATE:监控创建
    StandardWatchEventKinds.ENTRY_DELETE:监控删除
    StandardWatchEventKinds.ENTRY_MODIFY:监控修改

    3. 问题

    3.1 但是这会有一个问题,比如有两个path注册到同一个WatchService ,那么如何区分呢?

    不同的path呢?当然你可能说利用地址比较两者string address,但是我觉得太吃性能了,那么如何做了?

    首先想到,一般这种key都会带上attr,然而仔细查看源码后发现居然没有attr,有病是吧。。。 那么我们尝试自定义一个WatchEvent.key。



    结果发现抛出这个异常,我真的醉了。一人饮酒醉的那种。

    但是要怎么做才好了,比较字符串这种性能太低了,这么做我叶良辰不服。

    万般无奈,各种对比后,突然发现。


    这个dir 岂不是根path吗??

    然而我们要怎么获得这个dir呢?

    哈哈,看来作者早已看透一切了。

    于是我们尝试下,


    看来我们已经找到方法了,
    利用watchKey.watchable()和Path的引用比较来判断出,是否为该Path注册的类发出的事件
    同时,我们对ExtendedWatchEventModifier.FILE_TREE也做了测试,仍然发现 dir==path,也就是 watchKey.watchable() == path。

    3.2. 但是令人无可奈何的是,java无法监控文件的完整性,只能监控是否存在文件在此目录。

    也就是java可以发现这个文件,但是这个文件未必是完整的,也就是说这个文件正在被写入时被发现。
    面对这种情况个人觉得没什么比较好的解决方案,只能靠业务方法解决。

    方案一:
    我们每间隔一段时间对比下当前文件的size上一秒的size,看是否发生变化。
    缺点: 不好控制时间

    方案二:
    我们给个较长时间的wait,然后定时器调用去读数据

    相关文章

      网友评论

          本文标题:监控目录变化

          本文链接:https://www.haomeiwen.com/subject/qbqtwftx.html