Python写一个基于MD5的文件监听程序


Posted in Python onMarch 11, 2019

前述

写了一个基于MD5算法的文件监听程序,通过不同的文件能够生成不同的哈希函数,来实现实现判断文件夹中的文件的增加、修改、删除和过滤含有特定字符的文件名的文件。

需求说明

需要实现对一个文件夹下的文件的增加、修改和删除的监控, 一旦发生上述操作,则进行提示。可以选择过滤掉文件名中的特定字符和只监听文件名中含有特定字符的文件。

简述

首先,关于文件的增加、修改、删除的反馈,可以想到利用MD5等类似的加密算法,因为文件本身可以生成哈希值,只要文件内容或者文件名被修改过,就会生成和修改之前的哈希值不同的值,因此可以利用dict来存储,一个文件名对应一个哈希值来存储。其中增加和删除就对应一个新增加的键值对和一个减少的键值对,而修改则可以理解为删除了旧的文件、增加了一个新的文件。

MD5算法可以直接利用第三方的 hashlib 库来实现

m = hashlib.md5()
 myFile = open(full_path, 'rb')
 for line in myFile.readlines(): #以行为单位不断更新哈希值,避免文件过大导致一次产生大量开销
  m.update(line) #最后可以得到整个文件的哈希值

第二,关于滤掉文件名中的特定字符和只监听文件名中含有特定字符的文件的功能,这个其实非常简单,只需要用 list 分别对需要过滤和必须存在字符串进行存储, 然后利用标志位和字符串的子串包含性进行判断就可以了,只有满足条件的文件可以产生哈希值,产生哈希值也就意味着被监听了。

判断字符串中是否含有字串最常用的方法是 in 和 string 中的 find 方法,这里就不再赘述,可以直接看下面的代码

第三,因为要同时监控多个文件夹,所以必须要利用到线程来处理,创建一个线程池来存储线程, 线程利用了 threading 库,并且实现一个线程类来处理线程的操作

class myListener(threading.Thread):
thread1 = myListener(mydir, json_list_include, json_list_exclude) #生成线程

说明

需要额外说明的一点是,在传输需要监听的文件夹、必须包含的字段以及过滤字段的时候,我这里是利用配置文件的形式来存储的。说到底,是利用 toml 格式的数据进行的传输,toml格式和 json格式相比,用户的可读性更强一些,为了便于博客展示,因此利用了 toml 格式

首先利用代码生成了一下toml格式的文件,以后再想用的话,程序打包之后,可以直接修改配置文件来实现对程序的控制。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: JYRoooy
import collections
import json
import toml
if __name__ == '__main__':
 myOrderDict = collections.OrderedDict
 myOrderDict = {'dict':[{'path':'E:/testing', 'include':['log_'], 'exclude': ['.swp', '.swx', 'tmp']},{'path':'E:/tmp', 'include':['.record'], 'exclude': ['.tmp']}]}
 myToml = toml.dump(myOrderDict, open('E:/python/code/PythonProject/tomlConfig.txt','w+'))

toml文件

格式说明, 一个 dict 对应一个监听的文件夹和需要 过滤(exculde) 和 含有(include) 的字段,解释一下,这里的字段只是文件名的字段,监控 E:/testing 目录下的文件,要包含 log_ 字段的文件,且不包含 .swp .swx .tmp 字段的文件, 并且监控 E:/tmp 目录下的文件,要包含 .record 字段的文件,且不包含 .tmp 的文件。

Python写一个基于MD5的文件监听程序 

代码

完整程序的代码,具体解释可以看注释

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: JYRoooy
import toml
import hashlib
import os
import sys
import time
import importlib
import threading
importlib.reload(sys)

class myListener(threading.Thread):
 '''
 监听类
 '''
 def __init__(self, input_dir, filt_in, filt_ex): #文件夹路径,必须包含的字符,必须过滤的字符
 threading.Thread.__init__(self)
 self.input_dir = input_dir
 self.filt_in = filt_in
 self.filt_ex = filt_ex
 self.dict = {} #用来存储文件名和对应的哈希值
 self.file_list = [] #存储每一次扫描时的文件的文件名
 self.pop_list = [] #存储需要删除的文件名

 def run(self):
 while (1): #保证文件夹一直处于被监听的状态
  for cur_dir, dirs, files in os.walk(self.input_dir):
  if files != []:
   self.file_list = []
   for each_file_1 in files:
   each_file = each_file_1
   if self.filt_in: #判断文件名中是否有必须存在的字段
    flagone = 0
    for i in range(len(self.filt_in)):
    if self.filt_in[i] in each_file:
     flagone += 1
    if flagone == 0:
    continue

   if self.filt_ex: #判断文件名中是否有必须过滤掉的字段
    flagtwo = 0
    for i in range(len(self.filt_ex)):
    if self.filt_ex[i] in each_file:
     flagtwo = 1
    if flagtwo==1:
    continue

   self.file_list.append(each_file)
   full_path = os.path.join(cur_dir, each_file)
   m = hashlib.md5() #实例化md5算法

   myFile = open(full_path, 'rb')

   for line in myFile.readlines():
    m.update(line)
   if each_file not in self.dict.keys(): #如果当前的dict中没有这个文件,那么就添加进去
    self.dict[each_file] = m.hexdigest() #生成哈希值
    print('文件夹:' +cur_dir+ "中的文件名为:" + each_file + "的文件为新文件" + time.strftime('%Y-%m-%d %H:%M:%S',
           time.localtime(time.time())))
   if each_file in self.dict.keys() and self.dict[each_file] != m.hexdigest(): #如果当前dict中有这个文件,但是哈希值不同,说明文件被修改过,则需要对字典进行更新
    print('文件夹:' +cur_dir+ "中的文件名为:" + each_file + "的文件被修改于" + time.strftime('%Y-%m-%d %H:%M:%S',
           time.localtime(time.time())))
    self.dict[each_file] = m.hexdigest()
   myFile.close()
  pop_list = []
  for i in self.dict.keys():
   if i not in self.file_list: #当字典中有不在当前文件名列表中时,说明文件已经被删除
   print('文件夹:' +cur_dir+ '中的文件名为:' + i + "的文件已被删除!!!" + time.strftime('%Y-%m-%d %H:%M:%S',
          time.localtime(time.time())))
   pop_list.append(i)
  for i in pop_list:
   self.dict.pop(i)

  time.sleep(2)

if __name__ == '__main__':
 threads = [] #用来存储线程的线程池
 with open('E:/python/code/PythonProject/tomlConfig.txt','r+') as f: #读取toml格式的文件,并分解格式
 mytoml = toml.load(f)
 myList = mytoml['dict']
 for i in range(len(myList)): #因为可能同时需要监听多个文件夹,所以利用线程池处理多线程
  json_list_include = []
  json_list_exclude = []
  mydir = myList[i]['path']
  for sublist in range(len(myList[i]['include'])):
  json_list_include.append(myList[i]['include'][sublist])
  for sublist in range(len(myList[i]['exclude'])):
  json_list_exclude.append(myList[i]['exclude'][sublist])
  thread1 = myListener(mydir, json_list_include, json_list_exclude) #生成线程
  threads.append(thread1)

 for t in threads: #开启所有线程
  t.start();

运行结果

两个文件夹中的文件

Python写一个基于MD5的文件监听程序 

Python写一个基于MD5的文件监听程序

第一次运行程序, 可以看到已经按照过滤规则完成了过滤和监听

Python写一个基于MD5的文件监听程序

修改 loko.record 文件为 loko.re,再来看结果

Python写一个基于MD5的文件监听程序

可以看到已经完成了监听,因为 loko.re 文件,并符合监听的规则,所以不做出监听,而我们前面说过,一个修改相当于一个删除和一个新建操作,所以监听程序提示原文件被删除了

写在后面

其他的效果我就不一一展示了。

程序也没有实现很复杂的效果,代码已经上传 github -- https://github.com/JYRoy/MyFileListener (本地下载)

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
Python脚本简单实现打开默认浏览器登录人人和打开QQ的方法
Apr 12 Python
神经网络理论基础及Python实现详解
Dec 15 Python
浅谈用VSCode写python的正确姿势
Dec 16 Python
如何使用Python进行OCR识别图片中的文字
Apr 01 Python
在windows下使用python进行串口通讯的方法
Jul 02 Python
python实现大文本文件分割
Jul 22 Python
PyQt5 closeEvent关闭事件退出提示框原理解析
Jan 08 Python
Pycharm如何运行.py文件的方法步骤
Mar 03 Python
python 在右键菜单中加入复制目标文件的有效存放路径(单斜杠或者双反斜杠)
Apr 08 Python
将pycharm配置为matlab或者spyder的用法说明
Jun 08 Python
python interpolate插值实例
Jul 06 Python
python 简单的调用有道翻译
Nov 25 Python
Python使用reportlab模块生成PDF格式的文档
Mar 11 #Python
Python3转换html到pdf的不同解决方案
Mar 11 #Python
Python多项式回归的实现方法
Mar 11 #Python
Python实现定制自动化业务流量报表周报功能【XlsxWriter模块】
Mar 11 #Python
浅谈Python中的可迭代对象、迭代器、For循环工作机制、生成器
Mar 11 #Python
python使用selenium实现批量文件下载
Mar 11 #Python
利用Python实现微信找房机器人实例教程
Mar 10 #Python
You might like
微信公众号点击菜单即可打开并登录微站的实现方法
2014/11/14 PHP
PHP获取数组长度或某个值出现次数的方法
2015/02/11 PHP
php使用APC实现实时上传进度条功能
2015/10/26 PHP
php curl获取到json对象并转成数组array的方法
2018/05/31 PHP
js创建对象的区别示例介绍
2014/07/24 Javascript
jQuery找出网页上最高元素的方法
2015/03/20 Javascript
ajax读取数据后使用jqchart显示图表的方法
2015/06/10 Javascript
jQuery实现动态表单验证时文本框抖动效果完整实例
2015/08/21 Javascript
如何用jQuery实现ASP.NET GridView折叠伸展效果
2015/09/26 Javascript
浅析Javascript中bind()方法的使用与实现
2016/05/30 Javascript
极力推荐10个短小实用的JavaScript代码段
2016/08/03 Javascript
分析javascript中9 个常见错误阻碍你进步
2017/09/18 Javascript
vue中如何创建多个ueditor实例教程
2017/11/14 Javascript
JavaScript实现求最大公共子串的方法
2018/02/03 Javascript
小程序图片长按识别功能的实现方法
2018/08/30 Javascript
快速搭建Node.js(Express)用户注册、登录以及授权的方法
2019/05/09 Javascript
[56:58]VP vs Optic 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
python中ConfigParse模块的用法
2014/09/29 Python
python实现一次创建多级目录的方法
2015/05/15 Python
python定时器(Timer)用法简单实例
2015/06/04 Python
详解Python的Flask框架中的signals信号机制
2016/06/13 Python
初探利用Python进行图文识别(OCR)
2019/02/26 Python
pandas DataFrame 行列索引及值的获取的方法
2019/07/02 Python
python实现连连看辅助之图像识别延伸
2019/07/17 Python
Python跑循环时内存泄露的解决方法
2020/01/13 Python
解决Python数据可视化中文部分显示方块问题
2020/05/16 Python
利用CSS3制作简单的3d半透明立方体图片展示
2017/03/25 HTML / CSS
CSS3实现渐变背景兼容问题
2020/05/06 HTML / CSS
NBA欧洲商店(西班牙):NBA Europe Store ES
2019/04/16 全球购物
专业销售业务员求职信
2013/11/18 职场文书
超市业务员岗位职责
2013/12/05 职场文书
环境保护标语
2014/06/20 职场文书
个人委托书
2014/07/31 职场文书
党的群众路线教育实践活动个人批评与自我批评
2014/10/16 职场文书
首都博物馆观后感
2015/06/05 职场文书
教师节祝酒词
2015/08/11 职场文书