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而不是Java?
Mar 07 Python
Numpy数组的保存与读取方法
Apr 04 Python
python用post访问restful服务接口的方法
Dec 07 Python
matplotlib实现热成像图colorbar和极坐标图的方法
Dec 13 Python
python 同时运行多个程序的实例
Jan 07 Python
Python 200行代码实现一个滑动验证码过程详解
Jul 11 Python
程序员的七夕用30行代码让Python化身表白神器
Aug 07 Python
python传到前端的数据,双引号被转义的问题
Apr 03 Python
python 一维二维插值实例
Apr 22 Python
在服务器上安装python3.8.2环境的教程详解
Apr 26 Python
基于Pyinstaller打包Python程序并压缩文件大小
May 28 Python
教你使用TensorFlow2识别验证码
Jun 11 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
将OICQ数据转成MYSQL数据
2006/10/09 PHP
php 问卷调查结果统计
2015/10/08 PHP
Laravel框架实现发送短信验证功能代码
2016/06/06 PHP
thinkPHP基于ajax实现的菜单与分页示例
2016/07/12 PHP
php mysql_real_escape_string addslashes及mysql绑定参数防SQL注入攻击
2016/12/23 PHP
php设计模式之状态模式实例分析【星际争霸游戏案例】
2020/03/26 PHP
关于hashchangebroker和statehashable的补充文档
2011/08/08 Javascript
JavaScript String.replace函数参数实例说明
2013/06/06 Javascript
通过$(this)使用jQuery包装后的方法或属性
2014/05/18 Javascript
对new functionName()定义一个函数的理解
2014/05/22 Javascript
jquery attr方法获取input的checked属性问题
2014/05/26 Javascript
javascript中cookie对象用法实例分析
2015/01/30 Javascript
jQuery使用$.get()方法从服务器文件载入数据实例
2015/03/25 Javascript
js实现星星打分效果的方法
2020/07/05 Javascript
jQuery检测滚动条是否到达底部
2015/12/15 Javascript
nodejs更改项目端口号的方法
2018/05/13 NodeJs
在layer弹层layer.prompt中,修改placeholder的实现方法
2019/09/27 Javascript
vue-cli基础配置及webpack配置修改的完整步骤
2019/10/20 Javascript
js实现烟花特效
2020/03/02 Javascript
nuxt引入组件和公共样式的操作
2020/11/05 Javascript
vue中watch的用法汇总
2020/12/28 Vue.js
[03:10]超级美酒第四天 fy拉比克秀 大合集
2018/06/05 DOTA
pymssql ntext字段调用问题解决方法
2008/12/17 Python
python中对list去重的多种方法
2014/09/18 Python
Python基本语法之运算符功能与用法详解
2019/10/22 Python
Django配置文件代码说明
2019/12/04 Python
python lambda函数及三个常用的高阶函数
2020/02/05 Python
python软件都是免费的吗
2020/06/18 Python
HTML5 Video标签的属性、方法和事件汇总介绍
2015/04/24 HTML / CSS
台湾最大银发乐活百货:乐龄网
2018/05/21 全球购物
澳洲CFL商城:CHEMIST FOR LESS(中文)
2021/02/28 全球购物
环境工程大学生自荐信
2013/10/21 职场文书
八一慰问活动方案
2014/02/07 职场文书
售后服务承诺书
2014/03/26 职场文书
《春到梅花山》教学反思
2014/04/16 职场文书
运动会广播稿200字(10篇)
2014/10/12 职场文书