1. 程式人生 > >python實現目錄中制定內容查找

python實現目錄中制定內容查找

析構函數 exists del pla lse content sel 遍歷文件 start

#【函數實現代碼】------------------------------------------------------------------------------------------------------------------------------------------------------------------
#_*_coding=utf-8_*_
__author__ = ‘fang‘
__date__ = ‘2019/2/25 9:58‘

import os,codecs,chardet
from time import time
print(__file__)
thistime = time()

def endWith(s, *endstring):
"""
檢查文件名稱是否以endstring為結尾
:param s:
:param endstring:
:return:
"""
array = map(s.endswith, endstring)
if True in array:
return True
else:
return False

def writeResultLog(allExistsKeywords):
"""
獲取查詢結果的內容
將全部已搜索到的關鍵字列表中的內容保存到result.log文件中
:param allExistsKeywords:
:return:
"""

__logfilename = "result.log" # 相對路徑,文件在.py文件所在的目錄中
# 行分隔符
ls = os.linesep
# 結果日誌文件名
try:
fobj = open(__logfilename, ‘w‘,errors=‘ignore‘)
except IOError as e:
print("*** file open error:", e)

else:
# print(allExistsKeywords)
fobj.writelines([‘%s%s‘ % (keyword, ls) for keyword in allExistsKeywords])
fobj.close()
#判斷文件的編碼方式是否是utf8格式文件,是返回True否則False
# def existBOM(file_obj):
# code = file_obj.read(3)
# file_obj.close()
# if code == codecs.BOM_UTF8: # 判斷是否包含EF BB BF
# return True #如果要去掉頭部信息的話s = s[len(codecs.BOM_UTF8):]
# return False

def searchFilesContent(url):
"""
從searchkeywords.txt文件中初始化待搜索關鍵字列表
:param dirname:
:return:
"""
filename = "searchkeywords.txt" # 相對路徑,文件在.py文件所在的目錄中,搜索關鍵字的文件
# 待搜索關鍵字列表
allSearchKeywords = []
# 遍歷文件當前行已搜索到的關鍵字列表
existsKeywordsThisLine = []
allExistsKeywords = []
#放置所有搜索的文件
thistime = time()
try:
fobj = open(filename, ‘r‘)
except IOError as e:
print("*** file open error:", e)
else:
for eachLine in fobj:
allSearchKeywords.append(eachLine.strip(‘\n‘)) # 使用strip函數去除每行的換行符
fobj.close()

# 從excludekeywords.txt文件中初始化要排除的搜索關鍵字列表
filename = "excludekeywords.txt" # 相對路徑,文件在.py文件所在的目錄中
# 要排除的搜索關鍵字列表
allExcludedKeywords = []
try:
fobj = open(filename, ‘r‘)
except IOError as e:
print("*** file open error:", e)

else:
for eachLine in fobj:
allExcludedKeywords.append(eachLine.strip(‘\n‘)) # 使用strip函數去除每行的換行符
fobj.close()

# 從全部已搜索到的關鍵字列表排除掉不用搜索的關鍵字
for excluedkw in allExcludedKeywords:
if (excluedkw in allSearchKeywords):
allSearchKeywords.remove(excluedkw)
# 遍歷打開所有要在其中搜索內容的文件,若待搜索關鍵字列表為空,則不再繼續遍歷
for root, dirs, files in os.walk(url):
for file in files:
if endWith(file, ‘.txt‘, ‘.py‘): # 只在擴展名為‘.txt‘, ‘.py‘文件中搜索
# 打開文件
filename = root + os.sep + file # 絕對路徑
filename = filename.replace("\\","\\\\") # 將路徑中的單反斜杠替換為雙反斜杠,因為單反斜杠可能會導致將路徑中的內容進行轉義了,replace函數中"\\"表示單反斜杠,"\\\\"表示雙反斜杠
try:
# ==========開始讀取目錄中的文件遍歷查找的過程
fobj = codecs.open(filename, ‘r‘, ‘utf_8_sig‘, errors=‘ignore‘)
except IOError as e:
print("*** file open error:", e)
else:
# 遍歷文件的每一行
allSearchKeywords_1 = allSearchKeywords
for fileLine in fobj:
# 判斷當前行是否包含所有搜索關鍵字
for keyword in allSearchKeywords:
# 若包含,並添加到該行已搜索到的關鍵字列表中
if keyword.upper() in fileLine.upper(): # 將搜索關鍵字和該行文本內容都轉換為大寫後再進行匹配
existsKeywordsThisLine.append(keyword)

# 將這些搜索到的關鍵字添加到全部已搜索到的關鍵字列表中,並包含文件名信息
for keyword in existsKeywordsThisLine:
allExistsKeywords.append(keyword + "\t" + filename.replace("\\\\", "\\"))
if allSearchKeywords is None:
existsKeywordsThisLine = []
break
# 清空該行已搜索到的關鍵字列表內容
existsKeywordsThisLine = []
allSearchKeywords = allSearchKeywords_1
fobj.close()
# 全部文件遍歷結束
writeResultLog(allExistsKeywords)
print("DONE!", )
# 僅當本python模塊直接執行時,才執行如下語句,若被別的python模塊引入,則不執行
if __name__ == ‘__main__‘:
url = r"E:\python_data"
searchFilesContent(url)
search_time = time() - thistime
print(‘The code run {:.0f}m {:.0f}s‘.format(search_time // 60, search_time % 60))
#【類實現代碼】------------------------------------------------------------------------------------------------------------------------------------------------------------------

#_*_coding=utf-8_*_
__author__ = ‘fang‘
__date__ = ‘2019/2/25 9:58‘

import os,codecs,chardet
from multiprocessing import Process,Queue, Lock,current_process
from time import time
print(__file__)
class File_Search(object):
def
__init__(self, url):
"""初始化"""
self.__url = url

def endWith(self, s, *endstring):
"""
檢查文件名稱是否以endstring為結尾
:param s:
:param endstring:
:return:
"""
array = map(s.endswith, endstring)
if True in array:
return True
else:
return False

def
proc_read(self):
allExistsKeywords = []
while True:
try:
data = self.q.get()
allExistsKeywords.extend(data)
except:
print("get讀取查詢到的數據結束,數據是",allExistsKeywords)
self.writeResultLog(allExistsKeywords)
break
return
time() - self.thistime

def writeResultLog(self):
"""
獲取查詢結果的內容
將全部已搜索到的關鍵字列表中的內容保存到result.log文件中
:param allExistsKeywords:
:return:
"""
allExistsKeywords = []
while True:
try:
data = self.q.get(block=False)
allExistsKeywords.extend(data)
except :
print("差最後一步保存就可以了....")
break
self.__logfilename = "result.log" # 相對路徑,文件在.py文件所在的目錄中
# 行分隔符
ls = os.linesep
# 結果日誌文件名
try:
fobj = open(self.__logfilename, ‘w‘,errors=‘ignore‘)
except IOError as e:
print("*** file open error:", e)

else:
# print(allExistsKeywords)
fobj.writelines([‘%s%s‘ % (keyword, ls) for keyword in allExistsKeywords])
fobj.close()
return time() - self.thistime
#判斷文件的編碼方式是否是utf8格式文件,是返回True否則False
# def existBOM(file_obj):
# code = file_obj.read(3)
# file_obj.close()
# if code == codecs.BOM_UTF8: # 判斷是否包含EF BB BF
# return True #如果要去掉頭部信息的話s = s[len(codecs.BOM_UTF8):]
# return False

def searchFilesContent(self):
"""
從searchkeywords.txt文件中初始化待搜索關鍵字列表
:param dirname:
:return:
"""
self.__filename = "searchkeywords.txt" # 相對路徑,文件在.py文件所在的目錄中,搜索關鍵字的文件
# 待搜索關鍵字列表
self.__allSearchKeywords = []
# 遍歷文件當前行已搜索到的關鍵字列表
self.__existsKeywordsThisLine = []
# 全部已搜索到的關鍵字列表
self.__allExistsKeywords = []
#子進程創建Queue,並傳給各個子進程
self.q = Queue()
#放置所有搜索的文件
self.__filename_list = []
#放置所有進程的列表
self.process_list = []
#進程間鎖
self.lock = Lock()
self.thistime = time()
filename_list = []
try:
fobj = open(self.__filename, ‘r‘)
except IOError as e:
print("*** file open error:", e)
else:
for
eachLine in fobj:
self.__allSearchKeywords.append(eachLine.strip(\n)) # 使用strip函數去除每行的換行符
fobj.close()

# 從excludekeywords.txt文件中初始化要排除的搜索關鍵字列表
filename = "excludekeywords.txt" # 相對路徑,文件在.py文件所在的目錄中
# 要排除的搜索關鍵字列表
allExcludedKeywords = []
try:
fobj = open(filename, ‘r‘)
except IOError as e:
print("*** file open error:", e)

else:
for
eachLine in fobj:
allExcludedKeywords.append(eachLine.strip(\n)) # 使用strip函數去除每行的換行符
fobj.close()

# 從全部已搜索到的關鍵字列表排除掉不用搜索的關鍵字
for excluedkw in allExcludedKeywords:
if
(excluedkw in self.__allSearchKeywords):
self.__allSearchKeywords.remove(excluedkw)
# 遍歷打開所有要在其中搜索內容的文件,若待搜索關鍵字列表為空,則不再繼續遍歷
for root, dirs, files in os.walk(self.__url):
for
file in files:
if
self.endWith(file, ‘.txt‘, ‘.py‘): # 只在擴展名為‘.txt‘, ‘.py‘文件中搜索
# 打開文件
filename = root + os.sep + file # 絕對路徑
filename = filename.replace("\\","\\\\") # 將路徑中的單反斜杠替換為雙反斜杠,因為單反斜杠可能會導致將路徑中的內容進行轉義了,replace函數中"\\"表示單反斜杠,"\\\\"表示雙反斜杠
# filename_list.append(filename)
self.pp = Process(target=file_search.run, args=(self.q, self.lock, filename))
self.pp.start()
self.process_list.append(self.pp)
# return filename_list
# print("DONE!", )
def run(self, q, l, filename):
"""
多進程搜索文件,查找並記錄到進程隊列中
:param q: 進程間通信隊列
:param l: 進程間控制鎖
:param filename: 接收的文件的絕對路徑
:return:
"""
l.acquire()
try:
# ==========開始讀取目錄中的文件遍歷查找的過程
fobj = codecs.open(filename, ‘r‘, ‘utf_8_sig‘, errors=‘ignore‘)
except IOError as e:
print("*** file open error:", e)
else:
# 遍歷文件的每一行
for fileLine in fobj:
# 判斷當前行是否包含所有搜索關鍵字
for keyword in self.__allSearchKeywords:
# 若包含,並添加到該行已搜索到的關鍵字列表中
if keyword.upper() in fileLine.upper(): # 將搜索關鍵字和該行文本內容都轉換為大寫後再進行匹配
self.__existsKeywordsThisLine.append(keyword)

# 將這些搜索到的關鍵字添加到全部已搜索到的關鍵字列表中,並包含文件名信息
for keyword in self.__existsKeywordsThisLine:
self.__allExistsKeywords.append(keyword + "\t" + filename.replace("\\\\", "\\"))

# 清空該行已搜索到的關鍵字列表內容
self.__existsKeywordsThisLine = []
fobj.close()
# 全部文件遍歷結束
# self.writeResultLog(self.__allExistsKeywords)
q.put(self.__allExistsKeywords) #放置到隊列中
print(當前進程的名字是: ‘, current_process().name,已放置到隊列中....‘)
l.release()

def __del__(self):
"""
析構函數
join所完成的工作就是線程同步,即主線程任務結束之後,進入阻塞狀態,一直等待其他的子線程執行結束之後,主線程再終止
:param self:
:return:
"""
for process in self.process_list:
process.join()

# 僅當本python模塊直接執行時,才執行如下語句,若被別的python模塊引入,則不執行
if __name__ == ‘__main__‘:
url = r"E:\python_data"
file_search = File_Search(url)
file_search.searchFilesContent()
search_time = file_search.writeResultLog()
print(‘The code run {:.0f}m {:.0f}s‘.format(search_time // 60, search_time % 60))

以上函數實現和類實現的功能是一樣的,但是類實現需要的時間相比函數實現要長很多,貼在這裏期待幫助初學的我指點一二,如何進行代碼優化

python實現目錄中制定內容查找