溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

使用Python怎么實(shí)現(xiàn)一個(gè)MD5文件監(jiān)聽(tīng)程序

發(fā)布時(shí)間:2021-06-17 15:34:10 來(lái)源:億速云 閱讀:130 作者:Leah 欄目:開(kāi)發(fā)技術(shù)

使用Python怎么實(shí)現(xiàn)一個(gè)MD5文件監(jiān)聽(tīng)程序,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。

首先,關(guān)于文件的增加、修改、刪除的反饋,可以想到利用MD5等類似的加密算法,因?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)銷
  m.update(line) #最后可以得到整個(gè)文件的哈希值

第二,關(guān)于濾掉文件名中的特定字符和只監(jiān)聽(tīng)文件名中含有特定字符的文件的功能,這個(gè)其實(shí)非常簡(jiǎn)單,只需要用 list 分別對(duì)需要過(guò)濾和必須存在字符串進(jìn)行存儲(chǔ), 然后利用標(biāo)志位和字符串的子串包含性進(jìn)行判斷就可以了,只有滿足條件的文件可以產(chǎn)生哈希值,產(chǎn)生哈希值也就意味著被監(jiān)聽(tīng)了。

判斷字符串中是否含有字串最常用的方法是 in 和 string 中的 find 方法,這里就不再贅述,可以直接看下面的代碼

第三,因?yàn)橐瑫r(shí)監(jiān)控多個(gè)文件夾,所以必須要利用到線程來(lái)處理,創(chuàng)建一個(gè)線程池來(lái)存儲(chǔ)線程, 線程利用了 threading 庫(kù),并且實(shí)現(xiàn)一個(gè)線程類來(lái)處理線程的操作

class myListener(threading.Thread):
 thread1 = myListener(mydir, json_list_include, json_list_exclude) #生成線程

說(shuō)明

需要額外說(shuō)明的一點(diǎn)是,在傳輸需要監(jiān)聽(tīng)的文件夾、必須包含的字段以及過(guò)濾字段的時(shí)候,我這里是利用配置文件的形式來(lái)存儲(chǔ)的。說(shuō)到底,是利用 toml 格式的數(shù)據(jù)進(jìn)行的傳輸,toml格式和 json格式相比,用戶的可讀性更強(qiáng)一些,為了便于博客展示,因此利用了 toml 格式

首先利用代碼生成了一下toml格式的文件,以后再想用的話,程序打包之后,可以直接修改配置文件來(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 的文件。

使用Python怎么實(shí)現(xiàn)一個(gè)MD5文件監(jiān)聽(tīng)程序 

代碼

完整程序的代碼,具體解釋可以看注釋

#!/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)類
 '''
 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ǔ)線程的線程池
 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è)文件夾,所以利用線程池處理多線程
  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: #開(kāi)啟所有線程
  t.start();

運(yùn)行結(jié)果

兩個(gè)文件夾中的文件

使用Python怎么實(shí)現(xiàn)一個(gè)MD5文件監(jiān)聽(tīng)程序 

使用Python怎么實(shí)現(xiàn)一個(gè)MD5文件監(jiān)聽(tīng)程序

第一次運(yùn)行程序, 可以看到已經(jīng)按照過(guò)濾規(guī)則完成了過(guò)濾和監(jiān)聽(tīng)

使用Python怎么實(shí)現(xiàn)一個(gè)MD5文件監(jiān)聽(tīng)程序

修改 loko.record 文件為 loko.re,再來(lái)看結(jié)果

使用Python怎么實(shí)現(xiàn)一個(gè)MD5文件監(jiān)聽(tīng)程序

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI