麻辣GIS微信平台

更多 GIS 干货

微信关注不错过

「GIS教程」自动化监控文件夹变化的几种方法

前几天我们项目组老大出差,临走之前给我下了嘱托,说在机房的那台工作站上跑了一个GIS数据处理的程序,数据比较多,可能要等个把小时才出结果。让我有结果的时候通知他一下。老大交待的任务,我当然说好。可老大走后跑了2趟机房发现啥玩意没有,我心想老大不会把代码写错了吧。咱也不敢问,可一趟趟跑着,让我怎能安心的工(摸)作(鱼)?于是我想找一个偷懒的方法。

需求整理

我的想法是这样的,那个GIS程序的输出是一个特定的目录。那我只要保证有目录下有新的文件产生的时候,能够通知我就行。所以简化一下,分2步:

  1. 监听目录变化
  2. 有变化的时候通知我(发短信、邮件)

其实第二步比较简单,之前也用PHP写过邮件发送的工具,也可以调用一些发邮件短信的公有API。可怎么监听目录变化呢?目前收集了不少解决方案,做一个点评汇总。

FolderChangesView

老大的工作站装的也是windows,所以先找比较简单的方案,软件试用了几个,这个FolderChangesView算是比较有代表性的一个,但发现监控倒是有了,我想在特定事件下触发一些命令行,或者调用其他程度还有点问题,所以这个方案就放弃了。

类似的软件还有:Windows资源跟踪器、Directory Monitor之类的。这类软件的好处是简单易用,但对事件触发的支持不一,也比较重量,我一直坚持够用就好,所以跳过成熟软件方案。

fswatch

FSWatch是在Mac/Linux下非常出名的一个解决方案,项目地址:https://github.com/emcrisostomo/fswatch,也在一定程度上支持Windows。但对Windows的支持还是稍微弱了一点,比上面那种方案要灵活,当然使用难度也大一点。

PowerShell

经过上面 fswatch 的折腾,我心想我都为了一个小需求写代码了,那为什么不全写代码呢?于是我找到了这个解决方案,代码如下:

### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
    $watcher = New-Object System.IO.FileSystemWatcher
    $watcher.Path = "D:\source"
    $watcher.Filter = "*.*"
    $watcher.IncludeSubdirectories = $true
    $watcher.EnableRaisingEvents = $true  

### DEFINE ACTIONS AFTER AN EVENT IS DETECTED
    $action = { $path = $Event.SourceEventArgs.FullPath
                $changeType = $Event.SourceEventArgs.ChangeType
                $logline = "$(Get-Date), $changeType, $path"
                Add-content "D:\log.txt" -value $logline
              }    
### DECIDE WHICH EVENTS SHOULD BE WATCHED 
    Register-ObjectEvent $watcher "Created" -Action $action
    Register-ObjectEvent $watcher "Changed" -Action $action
    Register-ObjectEvent $watcher "Deleted" -Action $action
    Register-ObjectEvent $watcher "Renamed" -Action $action
    while ($true) {sleep 5}

使用方法:新建一个txt文件,将这段代码复制进去,然后修改$watcher.Path为自己要监控的目录,也支持过滤文件类型($watcher.Filter),以及是否监控子目录($watcher.IncludeSubdirectories),最后将这个文件保存成后缀为*.ps1类型,右击,使用Powershell运行即可。

这个方案我比较喜欢,原因是Win10原生支持,不需要装任何语言平台。但不好处就是,不跨平台,比如我想在Mac/Linux下使用,这个方案就不行了。另外PowerShell的调试比较复杂,就是这个原因让我放弃了。

Python

是的,它又来了。这是一个出圈的语言,使用 Python 的 watchdog 可以方便的实现这个功能。示例代码:

import sys
import time
import logging
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s - %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S')
    path = sys.argv[1] if len(sys.argv) > 1 else '.'

    # 生成事件处理器对象
    event_handler = LoggingEventHandler()

    # 生成监控器对象
    observer = Observer()
    # 注册事件处理器,配置监控目录
    observer.schedule(event_handler, path, recursive=True)
    # 监控器启动——创建线程
    observer.start()

    # 以下代码是为了保持主线程运行
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()

    # 主线程任务结束之后,进入阻塞状态,一直等待其他的子线程执行结束之后,主线程再终止
    observer.join()

NodeJS

JavaScript这几年的势头也是很猛,使用NodeJS的chokidar 库可以方便的实现这个功能。

项目地址:https://github.com/paulmillr/chokidar

后话

既然已经用了编程语言了,那C++、C#、Java之类的都是可以的,不过这种小工具,使用Node或者Python是正合适,一个小程序就搞定了。有了这个玩意,我就可以安心做其他事件了。

PS:终于在老大出差一天后,出了结果。看来老大的代码写对了,得亏没问。

相关阅读

麻辣GIS-Sailor

作者:

GIS爱好者,学GIS,更爱玩GIS。

声明

1.本文所分享的所有需要用户下载使用的内容(包括但不限于软件、数据、图片)来自于网络或者麻辣GIS粉丝自行分享,版权归该下载资源的合法拥有者所有,如有侵权请第一时间联系本站删除。

2.下载内容仅限个人学习使用,请切勿用作商用等其他用途,否则后果自负。

手机阅读
公众号关注
知识星球
手机阅读
麻辣GIS微信公众号关注
最新GIS干货
关注麻辣GIS知识星球
私享圈子

已有 2 条评论

  1. 麻辣GIS-hh
    1#
    hh  · 2020-12-24 16:59

    python的 os.listdir感觉更简单哈

      1. 麻辣GIS-Sailor
        Sailor  · 2021-01-03 11:28

        那个只是列出文件来,我需要的监控,有新的增加能提醒到我。

留言板(小编看到第一时间回复) 取消回复