Python寫(xiě)一個(gè)基于MD5的文件監(jiān)聽(tīng)程序
前述
寫(xiě)了一個(gè)基于MD5算法的文件監(jiān)聽(tīng)程序,通過(guò)不同的文件能夠生成不同的哈希函數(shù),來(lái)實(shí)現(xiàn)實(shí)現(xiàn)判斷文件夾中的文件的增加、修改、刪除和過(guò)濾含有特定字符的文件名的文件。
需求說(shuō)明
需要實(shí)現(xiàn)對(duì)一個(gè)文件夾下的文件的增加、修改和刪除的監(jiān)控, 一旦發(fā)生上述操作,則進(jìn)行提示??梢赃x擇過(guò)濾掉文件名中的特定字符和只監(jiān)聽(tīng)文件名中含有特定字符的文件。
簡(jiǎn)述
首先,關(guān)于文件的增加、修改、刪除的反饋,可以想到利用MD5等類(lèi)似的加密算法,因?yàn)槲募旧砜梢陨晒V?,只要文件?nèi)容或者文件名被修改過(guò),就會(huì)生成和修改之前的哈希值不同的值,因此可以利用dict來(lái)存儲(chǔ),一個(gè)文件名對(duì)應(yīng)一個(gè)哈希值來(lái)存儲(chǔ)。其中增加和刪除就對(duì)應(yīng)一個(gè)新增加的鍵值對(duì)和一個(gè)減少的鍵值對(duì),而修改則可以理解為刪除了舊的文件、增加了一個(gè)新的文件。
MD5算法可以直接利用第三方的 hashlib 庫(kù)來(lái)實(shí)現(xiàn)
m = hashlib.md5() myFile = open(full_path, 'rb') for line in myFile.readlines(): #以行為單位不斷更新哈希值,避免文件過(guò)大導(dǎo)致一次產(chǎn)生大量開(kāi)銷(xiāo) m.update(line) #最后可以得到整個(gè)文件的哈希值
第二,關(guān)于濾掉文件名中的特定字符和只監(jiān)聽(tīng)文件名中含有特定字符的文件的功能,這個(gè)其實(shí)非常簡(jiǎn)單,只需要用 list 分別對(duì)需要過(guò)濾和必須存在字符串進(jìn)行存儲(chǔ), 然后利用標(biāo)志位和字符串的子串包含性進(jìn)行判斷就可以了,只有滿(mǎn)足條件的文件可以產(chǎn)生哈希值,產(chǎn)生哈希值也就意味著被監(jiān)聽(tīng)了。
判斷字符串中是否含有字串最常用的方法是 in 和 string 中的 find 方法,這里就不再贅述,可以直接看下面的代碼
第三,因?yàn)橐瑫r(shí)監(jiān)控多個(gè)文件夾,所以必須要利用到線(xiàn)程來(lái)處理,創(chuàng)建一個(gè)線(xiàn)程池來(lái)存儲(chǔ)線(xiàn)程, 線(xiàn)程利用了 threading 庫(kù),并且實(shí)現(xiàn)一個(gè)線(xiàn)程類(lèi)來(lái)處理線(xiàn)程的操作
class myListener(threading.Thread):
thread1 = myListener(mydir, json_list_include, json_list_exclude) #生成線(xiàn)程
說(shuō)明
需要額外說(shuō)明的一點(diǎn)是,在傳輸需要監(jiān)聽(tīng)的文件夾、必須包含的字段以及過(guò)濾字段的時(shí)候,我這里是利用配置文件的形式來(lái)存儲(chǔ)的。說(shuō)到底,是利用 toml 格式的數(shù)據(jù)進(jìn)行的傳輸,toml格式和 json格式相比,用戶(hù)的可讀性更強(qiáng)一些,為了便于博客展示,因此利用了 toml 格式
首先利用代碼生成了一下toml格式的文件,以后再想用的話(huà),程序打包之后,可以直接修改配置文件來(lái)實(shí)現(xiàn)對(duì)程序的控制。
#!/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文件
格式說(shuō)明, 一個(gè) dict 對(duì)應(yīng)一個(gè)監(jiān)聽(tīng)的文件夾和需要 過(guò)濾(exculde) 和 含有(include) 的字段,解釋一下,這里的字段只是文件名的字段,監(jiān)控 E:/testing 目錄下的文件,要包含 log_ 字段的文件,且不包含 .swp .swx .tmp 字段的文件, 并且監(jiān)控 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): ''' 監(jiān)聽(tīng)類(lèi) ''' def __init__(self, input_dir, filt_in, filt_ex): #文件夾路徑,必須包含的字符,必須過(guò)濾的字符 threading.Thread.__init__(self) self.input_dir = input_dir self.filt_in = filt_in self.filt_ex = filt_ex self.dict = {} #用來(lái)存儲(chǔ)文件名和對(duì)應(yīng)的哈希值 self.file_list = [] #存儲(chǔ)每一次掃描時(shí)的文件的文件名 self.pop_list = [] #存儲(chǔ)需要?jiǎng)h除的文件名 def run(self): while (1): #保證文件夾一直處于被監(jiān)聽(tīng)的狀態(tài) 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: #判斷文件名中是否有必須過(guò)濾掉的字段 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() #實(shí)例化md5算法 myFile = open(full_path, 'rb') for line in myFile.readlines(): m.update(line) if each_file not in self.dict.keys(): #如果當(dāng)前的dict中沒(méi)有這個(gè)文件,那么就添加進(jìn)去 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(): #如果當(dāng)前dict中有這個(gè)文件,但是哈希值不同,說(shuō)明文件被修改過(guò),則需要對(duì)字典進(jìn)行更新 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: #當(dāng)字典中有不在當(dāng)前文件名列表中時(shí),說(shuō)明文件已經(jīng)被刪除 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 = [] #用來(lái)存儲(chǔ)線(xiàn)程的線(xiàn)程池 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)): #因?yàn)榭赡芡瑫r(shí)需要監(jiān)聽(tīng)多個(gè)文件夾,所以利用線(xiàn)程池處理多線(xiàn)程 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) #生成線(xiàn)程 threads.append(thread1) for t in threads: #開(kāi)啟所有線(xiàn)程 t.start();
運(yùn)行結(jié)果
兩個(gè)文件夾中的文件
第一次運(yùn)行程序, 可以看到已經(jīng)按照過(guò)濾規(guī)則完成了過(guò)濾和監(jiān)聽(tīng)
修改 loko.record 文件為 loko.re,再來(lái)看結(jié)果
可以看到已經(jīng)完成了監(jiān)聽(tīng),因?yàn)?loko.re 文件,并符合監(jiān)聽(tīng)的規(guī)則,所以不做出監(jiān)聽(tīng),而我們前面說(shuō)過(guò),一個(gè)修改相當(dāng)于一個(gè)刪除和一個(gè)新建操作,所以監(jiān)聽(tīng)程序提示原文件被刪除了
寫(xiě)在后面
其他的效果我就不一一展示了。
程序也沒(méi)有實(shí)現(xiàn)很復(fù)雜的效果,代碼已經(jīng)上傳 github -- https://github.com/JYRoy/MyFileListener (本地下載)
好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
- 如何利用python生成MD5并去重
- Python常用base64 md5 aes des crc32加密解密方法匯總
- python MD5加密的示例
- Python實(shí)現(xiàn)常見(jiàn)的幾種加密算法(MD5,SHA-1,HMAC,DES/AES,RSA和ECC)
- python中的socket實(shí)現(xiàn)ftp客戶(hù)端和服務(wù)器收發(fā)文件及md5加密文件
- Python實(shí)現(xiàn)檢測(cè)文件的MD5值來(lái)查找重復(fù)文件案例
- Python生成MD5值的兩種方法實(shí)例分析
- python3中的md5加密實(shí)例
- python 獲取字符串MD5值方法
- 用python計(jì)算文件的MD5值
相關(guān)文章
Python根據(jù)詞頻信息(xlsx、csv文件)繪制詞云圖全過(guò)程(wordcloud)
這篇文章主要給大家介紹了關(guān)于Python根據(jù)詞頻信息(xlsx、csv文件)繪制詞云圖的相關(guān)資料,wordcloud是基于Python開(kāi)發(fā)的詞云生成庫(kù),功能強(qiáng)大使用簡(jiǎn)單,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-06-06python實(shí)現(xiàn)定制交互式命令行的方法
這篇文章主要介紹了python實(shí)現(xiàn)定制交互式命令行的方法,需要的朋友可以參考下2014-07-07python實(shí)現(xiàn)簡(jiǎn)單的俄羅斯方塊
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)簡(jiǎn)單的俄羅斯方塊,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01OneFlow源碼解析之Eager模式下Tensor存儲(chǔ)管理
這篇文章主要為大家介紹了OneFlow源碼解析之Eager模式下Tensor的存儲(chǔ)管理實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04Python實(shí)現(xiàn)畫(huà)圖軟件功能方法詳解
這篇文章主要介紹了 Python實(shí)現(xiàn)畫(huà)圖軟件功能方法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07python中threading和queue庫(kù)實(shí)現(xiàn)多線(xiàn)程編程
這篇文章主要介紹了python中threading和queue庫(kù)實(shí)現(xiàn)多線(xiàn)程編程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02