前述
写了一个基于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 的文件。
代码
完整程序的代码,具体解释可以看注释
#!/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();
运行结果
两个文件夹中的文件
第一次运行程序, 可以看到已经按照过滤规则完成了过滤和监听
修改 loko.record 文件为 loko.re,再来看结果
可以看到已经完成了监听,因为 loko.re 文件,并符合监听的规则,所以不做出监听,而我们前面说过,一个修改相当于一个删除和一个新建操作,所以监听程序提示原文件被删除了
写在后面
其他的效果我就不一一展示了。
程序也没有实现很复杂的效果,代码已经上传 github -- https://github.com/JYRoy/MyFileListener (本地下载)
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]