引言

上一篇介绍完了观察者模式的原理,本篇想就此再介绍一个小应用,虽然我也就玩了一下午,是当时看observer正好找到的,以及还有Django-observer,但Django很久没用了,所以提下这个作为一个笔记。

watchdog介绍

Watchdog的中文的“看门狗”,有保护的意思。最早引入Watchdog是在单片机系统中,由于单片机的工作环境容易受到外界磁场的干扰,导致程序“跑飞”,造成整个系统无法正常工作,因此,引入了一个“看门狗”,对单片机的运行状态进行实时监测,针对运行故障做一些保护处理,譬如让系统重启。这种Watchdog属于硬件层面,必须有硬件电路的支持。

Linux也引入了Watchdog,在Linux内核下,当Watchdog启动后,便设定了一个定时器,如果在超时时间内没有对/dev/Watchdog进行写操作,则会导致系统重启。通过定时器实现的Watchdog属于软件层面。

嗯,这样的嘛。好像上面这段话没啥用,连成为谈资都不行。我也是直接百度第一篇复制一段当做介绍,习惯使然。(手动狗头)

在python中文件监控主要有两个库,一个是pyinotify ( https://github.com/seb-m/pyinotify/wiki ),一个是watchdog(http://pythonhosted.org/watchdog/)。pyinotify依赖于Linux平台的inotify,后者则对不同平台的的事件都进行了封装。

watchdog使用

在python中可以直接通过pip安装:

pip install watchdog -i https://pypi.tuna.tsinghua.edu.cn/simple

watchdog主要采用观察者模型。主要有三个角色:observer,event_handler,被监控的文件夹。三者原本是独立的,主要通过observer.schedule函数将三者串起来。

事件类(event):

watchdog.events.FileSystemEvent(event_type,

src_path,

is_directory=False)

event_type为事件类型,为moved、deleted、created或modified的其中之一

src_path为触发该事件的文件或目录路径

is_directory为该事件是否由一个目录触发

watchdog能实现在不同平台下都能兼容,并监控相关事件,但是如果在Windows下,是有很多问题的,具体的会在后面提出,那懂了事件类,我们就可以看看事件处理方法:

那现在有了处

def on_created(event):

print(f"hey, {event.src_path} has been created!")

def on_deleted(event):

print(f"Someone deleted {event.src_path}!")

def on_modified(event):

print(f"hey buddy, {event.src_path} has been modified")

def on_moved(event):

print(f"ok ok ok, someone moved {event.src_path} to {event.dest_path}")

理事件的函数,就需要在主程序里创建一个监听程序了:

path = "."

go_recursively = True

my_observer = Observer()

my_observer.schedule(my_event_handler, path, recursive=True)

observer.schedule(event_handler, path, recursive=False)相当于实例化监听对象,监控指定路径path,该路径触发任何事件都会调用event_handler来处理,如果path是目录,则recursive=True则会递归监控该目录的所有变化。每一次调用schedule()对一个路径进行监控处理就叫做一个watch,schedule()方法会返回这个watch,接着可以对这个watch做其他操作,如为该watch增加多个event处理器等。

那了解到这里,就可以写一个demo程序进行测试了:

from watchdog.observers import Observer

from watchdog.events import *

import time

class FileEventHandler(FileSystemEventHandler):

def __init__(self):

FileSystemEventHandler.__init__(self)

def on_moved(self, event):

if event.is_directory:

print("directory moved from {0} to {1}".format(event.src_path,event.dest_path))

else:

print("file moved from {0} to {1}".format(event.src_path,event.dest_path))

def on_created(self, event):

if event.is_directory:

print("directory created:{0}".format(event.src_path))

else:

print("file created:{0}".format(event.src_path))

def on_deleted(self, event):

if event.is_directory:

print("directory deleted:{0}".format(event.src_path))

else:

print("file deleted:{0}".format(event.src_path))

def on_modified(self, event):

if event.is_directory:

print("directory modified:{0}".format(event.src_path))

else:

print("file modified:{0}".format(event.src_path))

if __name__ == "__main__":

observer = Observer()

event_handler = FileEventHandler()

observer.schedule(event_handler,r"D:\code\dingshirenwu",True)

observer.start()

try:

while True:

time.sleep(1)

except KeyboardInterrupt:

observer.stop()

observer.join()

代码参考自python中文件变化监控-watchdog

不过这里只是监控了单个,我们可以通过循环来监控多个文件夹:

dirs = [r'D:\code\dingshirenwu', r'D:\code\tuiliu']

for dir in dirs:

event_handler = FileEventHandler()

observer.schedule(event_handler, dir, True)

observer.start()

到此为止,基本上已经知道这个模块到底怎么用了,但当我准备在事件里加一个上传机制的时候,发现Windows下的一些问题。Windows下watchdog并没有权限去监控文件是否完整。即我有一个大文件,2G的视频即使是内部百M传输,也需要几十秒的时间,但watchdog只能接收到文件创建的时间就立刻进行了文件上传,而不是同Linux并使用的inotify,似乎没有什么好的办法,我也只是能上传一些比较小的如图片等秒传秒下的文件,下面为我的代码:

import logging

import queue

import threading

import time

import watchdog.observers as observers

import watchdog.events as events

from ftplib import FTP

logger = logging.getLogger(__name__)

SENTINEL = None

def upload(f, remote_path, local_path):

fp = open(local_path, "rb")

buf_size = 1024

f.storbinary("STOR {}".format(remote_path), fp, buf_size)

fp.close()

class MyEventHandler(events.FileSystemEventHandler):

def on_any_event(self, event):

super(MyEventHandler, self).on_any_event(event)

queue.put(event)

def __init__(self, queue):

self.queue = queue

def process(queue):

while True:

event = queue.get()

logger.info(event)

print(event.key) # tuple

('modified', 'C:\\Users\\admin\\Desktop\\公司文件\\test\\GitHub\\isadb\\.idea', True)

if (event.key)[0] == "created":

upload(ftp, remote_path, event.src_path)

if __name__ == '__main__':

logging.basicConfig(level=logging.DEBUG,

format='[%(asctime)s %(threadName)s] %(message)s',

datefmt='%H:%M:%S')

ftp = FTP()

ftp.connect("x.x.x.x", 21) # 第一个参数可以是ftp服务器的ip或者域名,第二个参数为ftp服务器的连接端口,默认为21

ftp.login(username, password) # 匿名登录直接使用ftp.login()

queue = queue.Queue()

num_workers = 4

pool = [threading.Thread(target=process, args=(queue,)) for i in range(num_workers)]

for t in pool:

t.daemon = True

t.start()

event_handler = MyEventHandler(queue)

observer = observers.Observer()

observer.schedule(

event_handler,

path=r'C:\Users\admin\Desktop\公司文件\test\GitHub\isadb',

recursive=True)

observer.start()

try:

while True:

time.sleep(1)

except KeyboardInterrupt:

observer.stop()

observer.join()

建立了一个工作线程池,而不是累积文件系统事件,该线程从一个公共队列中获取任务。上传文件我是写了一个类调用,但那个文件找不到了。。所以改用了函数,这里会有问题是:IOError: [Errno 13] Permission denied: u'D:\pycharm\test.mp4'

然后再Stack Overflow找到了一个解决方案:当上传一个大文件的时候,同时上传一个空文本,记录这个文件的大小,然后对这个文件进行轮询,只有当该文件的大小不再发生变化时,我们认为这个文件已经生成成功,这时再考虑上传,不过我也就写个demo,太麻烦了。。。如果有人有更好的方式,可以评论或者私信我。

到此这篇关于python中watchdog文件监控与检测上传的文章就介绍到这了,更多相关python watchdog监控文件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

python watchdog 同时检测到多个事件_python中watchdog文件监控与检测上传功能相关推荐

  1. pyaudio:基于pyaudio利用Python编程从电脑端录制音频保存到指定文件夹+将录音上传服务器+录音进行识别并转为文本保存

    pyaudio:基于pyaudio利用Python编程从电脑端录制音频保存到指定文件夹+将录音上传服务器+录音进行识别并转为文本保存 目录 输出结果 代码实现 输出结果 代码实现 # -*- codi ...

  2. 道路运输车辆卫星定位系统企业监控平台标准符合性检测和道路运输车辆卫星定位系统企业视频监控平台检测攻略...

    卫星定位平台部标平台检测阶段步骤道路运输车辆卫星定位系统企业监控平台标准符合性检测和道路运输车辆卫星定位系统企业视频监控平台检测攻略 最新更新2019年9月9日16:21:37     步骤1.报名 ...

  3. python读取视频占用内存太大_Python 读取大文件内存占用检测示例

    导读热词对python这个高级语言感兴趣的小伙伴,下面一起跟随编程之家 jb51.cc的小编两巴掌来看看吧! python读写文件的api都很简单,一不留神就容易踩"坑".笔者记录 ...

  4. python实现文件上传功能_python实现上传下载文件功能

    最近刚学python,遇到上传下载文件功能需求,记录下! django web项目,前端上传控件用的是uploadify. 文件上传 - 后台view 的 Python代码如下: @csrf_exem ...

  5. python csv读写方法_python中csv文件的若干读写方法小结

    如下所示: //用普通文本文件方式打开和操作 with open("'file.csv'") as cf: lines=cf.readlines() ...... //用普通文本方 ...

  6. python显示目录中的文件_Python中的文件和目录操作实现

    Python中的文件和目录操作实现 对于文件和目录的处理,虽然可以通过操作系统命令来完成,但是Python语言为了便于开发人员以编程的方式处理相关工作,提供了许多处理文件和目录的内置函数.重要的是,这 ...

  7. python线上编辑问题_python django - static文件处理与线上部署测试

    static文件相关操作涉及: a. 文件位置与访问路径映射 b. setting.py与static相关配置 STATIC_URL STATIC_ROOT STATICFILES_DIRS c. h ...

  8. python语句结束符_python中判断文件结束符的具体方法

    python中判断文件结束符的方法:可以使用try except语句块来进行判断. 具体使用方法:[try:while True:s = input() except EOFError: pass]. ...

  9. python上传文件进度_python实现进度条--主要用在上传下载文件

    在python中进行socket上传文件的时候使用进度条,然后在网上找了好久,找寻相关的进度的条的使用,看了几个,发现总是无法进行调用,主要原因是在进行上传文件的时候,每次传送的数据量是固定的,数据的 ...

最新文章

  1. python函数概述_Python概述
  2. 面向对象编程(一)——面向对象和面向过程
  3. c++学习笔记之友元函数
  4. myeclipse hbm2java_myeclipse试用小记----Hibernate多对一双向关联(2)
  5. Laravel大型项目系列教程(三)之发表文章
  6. SaeStorage使用示例
  7. 乔安监控云存储_智能运维丨全栈监控,护航云上业务
  8. H3C 三种生成树协议特性的比较
  9. bmp文件格式_一次性解决CAD转换成BMP格式图片的问题
  10. 通过思科构造局域网_从Cisco DNA中心的管理的和设置的非结构Catalyst 9800无线局域网控制器...
  11. 【linux基础】cuDNN版本查询
  12. hdu 1873“看病要排队”——优先队列的应用
  13. SSH服务配置公钥及双重验证
  14. 如何通过数据分析进行活动效果评估
  15. Win10查看已存储WiFi密码的两种方法
  16. Adaptive AutoSAR 标准介绍
  17. React.js介绍
  18. 刷票投票的自动运行脚本
  19. The Preliminary Contest for ICPC Asia Shanghai 2019 B. Light bulbs(卡了线段树空间的思维题)
  20. Android LeakCanary使用详细教程

热门文章

  1. setTimeout() 方法的返回值
  2. STM32寄存器与输入捕获
  3. Dockerfile使用,怎么通过Dockerfile完成docker映像配置
  4. Nginx反向代理负载均衡时,验证码不正确
  5. C语言再学习 -- 转义字符
  6. zcmu1209(dfs)
  7. Java中abstract类和abstract方法的相关问题
  8. go int 转切片_DW-Go语言编程-Task06-数组、切片
  9. vysor原理代码实现(V2.0)
  10. BZOJ 4553: [Tjoi2016Heoi2016]序列