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模块详解
Sep 15 Python
详解django三种文件下载方式
Apr 06 Python
Python3实现的字典、列表和json对象互转功能示例
May 22 Python
python实现换位加密算法的示例
Oct 14 Python
python 列表递归求和、计数、求最大元素的实例
Nov 28 Python
django小技巧之html模板中调用对象属性或对象的方法
Nov 30 Python
Python3中的bytes和str类型详解
May 02 Python
Win10系统下安装labelme及json文件批量转化方法
Jul 30 Python
解决Django连接db遇到的问题
Aug 29 Python
Python使用lambda抛出异常实现方法解析
Aug 20 Python
浅谈Python 中的复数问题
May 19 Python
Python 如何利用ffmpeg 处理视频素材
Nov 27 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
全国FM电台频率大全 - 9 上海市
2020/03/11 无线电
整合了前面的PHP数据库连接类~~做成一个分页类!
2006/11/25 PHP
PHP 截取字符串 分别适合GB2312和UTF8编码情况
2009/02/12 PHP
自动把纯文本转换成Web页面的php代码
2009/08/27 PHP
paypal即时到账php实现代码
2010/11/28 PHP
PHP内核探索:哈希表碰撞攻击原理
2015/07/31 PHP
PHP扩展框架之Yaf框架的安装与使用
2016/05/18 PHP
基于laravel Request的所有方法详解
2019/09/29 PHP
也说JavaScript中String类的replace函数
2011/09/22 Javascript
js加载之使用DOM方法动态加载Javascript文件
2013/11/08 Javascript
javascript控制在光标位置插入文字适合表情的插入
2014/06/09 Javascript
js采用concat和sort将N个数组拼接起来的方法
2016/01/21 Javascript
JavaScript中关联原型链属性特性
2016/02/13 Javascript
layer更改皮肤的实现方法
2019/09/11 Javascript
JavaScript实现拖动对话框效果的实现代码
2020/10/12 Javascript
Python中的random()方法的使用介绍
2015/05/15 Python
Python制作简易注册登录系统
2016/12/15 Python
numpy中矩阵合并的实例
2018/06/15 Python
对tensorflow 的模型保存和调用实例讲解
2018/07/28 Python
Python 从一个文件中调用另一个文件的类方法
2019/01/10 Python
详解将Pandas中的DataFrame类型转换成Numpy中array类型的三种方法
2019/07/06 Python
详解Python time库的使用
2019/10/10 Python
ubuntu 安装pyqt5和卸载pyQt5的方法
2020/03/24 Python
PyCharm Anaconda配置PyQt5开发环境及创建项目的教程详解
2020/03/24 Python
基于python实现操作git过程代码解析
2020/07/27 Python
matplotlib bar()实现百分比堆积柱状图
2021/02/24 Python
如何开启linux的ssh服务
2013/06/03 面试题
班主任评语大全
2014/04/26 职场文书
教师师德演讲稿
2014/05/06 职场文书
职业规划实施方案
2014/06/10 职场文书
政法干警核心价值观心得体会
2014/09/11 职场文书
红色经典观后感
2015/06/18 职场文书
在Java中Collection的一些常用方法总结
2021/06/13 Java/Android
Python中Selenium对Cookie的操作方法
2021/07/09 Python
使用python创建股票的时间序列可视化分析
2022/03/03 Python
解决Mysql中的innoDB幻读问题
2022/04/29 MySQL