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日期操作学习笔记
Oct 07 Python
apache部署python程序出现503错误的解决方法
Jul 24 Python
Python入门之三角函数sin()函数实例详解
Nov 08 Python
pip matplotlib报错equired packages can not be built解决
Jan 06 Python
python的pip安装以及使用教程
Sep 18 Python
Python中的集合介绍
Jan 28 Python
深入了解和应用Python 装饰器 @decorator
Apr 02 Python
Python如何调用外部系统命令
Aug 07 Python
Python OrderedDict的使用案例解析
Oct 25 Python
Python如何在单元测试中给对象打补丁
Aug 03 Python
python math模块的基本使用教程
Jan 16 Python
Python实现滑雪小游戏
Sep 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
PHP合并静态文件详解
2014/11/14 PHP
JavaScript与函数式编程解释
2007/04/27 Javascript
利用JS重写Cognos右键菜单的实现代码
2010/04/11 Javascript
js 判断一个元素是否在页面中存在
2012/12/27 Javascript
JavaScript设计模式之原型模式(Object.create与prototype)介绍
2014/12/28 Javascript
JavaScript实现找质数代码分享
2015/03/24 Javascript
Javascript中prototype属性实现给内置对象添加新的方法
2015/05/14 Javascript
一不小心就做错的JS闭包面试题
2015/11/25 Javascript
jQuery移动web开发之页面跳转和加载外部页面的实现
2015/12/04 Javascript
jquery+json实现分页效果
2016/03/07 Javascript
javascript类型系统_正则表达式RegExp类型详解
2016/06/24 Javascript
jquery插件autocomplete用法示例
2016/07/01 Javascript
javascript中Number的方法小结
2016/11/21 Javascript
JavaScript获取服务器端时间的方法
2016/11/29 Javascript
vue 中directive功能的简单实现
2018/01/05 Javascript
python中numpy的矩阵、多维数组的用法
2018/02/05 Python
python深度优先搜索和广度优先搜索
2018/02/07 Python
基于数据归一化以及Python实现方式
2018/07/11 Python
Python 实现「食行生鲜」签到领积分功能
2018/09/26 Python
Python 带有参数的装饰器实例代码详解
2018/12/06 Python
详解Python_shutil模块
2019/03/15 Python
什么是python类属性
2020/06/10 Python
pytorch加载自己的图像数据集实例
2020/07/07 Python
python实现暗通道去雾算法的示例
2020/09/27 Python
Pycharm配置autopep8实现流程解析
2020/11/28 Python
HTML5本地存储之Database Storage应用介绍
2013/01/06 HTML / CSS
HTML5新增加标签和功能概述
2016/09/05 HTML / CSS
将"引用"作为函数参数有哪些特点
2013/04/05 面试题
班级德育工作实施方案
2014/02/21 职场文书
元旦联欢会主持词
2014/03/26 职场文书
2014年村党支部工作总结
2014/12/04 职场文书
2015年护士长个人工作总结
2015/04/24 职场文书
信仰观后感
2015/06/03 职场文书
校运会广播稿
2015/08/19 职场文书
Java Spring读取和存储详细操作
2022/08/05 Java/Android
HTML5中的DOCUMENT.VISIBILITYSTATE属性详解
2023/05/07 HTML / CSS