123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- import zlib
- import sys
- import ctypes
- import datetime
- import struct
- import re
- import os
- import platform
- # 从文件中读取block_size大小,计算CRC32
- def crc32_simple(filepath):
- try:
- with open(filepath, 'rb') as f:
- s = f.read(1024 * 1024)
- return zlib.crc32(s, 0)
- except Exception as e:
- print(str(e))
- return 0
- # 计算整个文件的crc32
- def crc32_file(filepath):
- crc = 0
- try:
- fd = open(filepath, 'rb')
- while True:
- buffer = fd.read(1024 * 1024)
- if len(buffer) == 0: # EOF or file empty. return hashes
- fd.close()
- if sys.version_info[0] < 3 and crc < 0:
- crc += 2 ** 32
- return crc # 返回的是十进制的值
- crc = zlib.crc32(buffer, crc)
- except Exception as e:
- if sys.version_info[0] < 3:
- error = unicode(e)
- else:
- error = str(e)
- print(error)
- return 0
- # 根据文件大小 返回合理区间,16473740 bytes--> 15.727 MB
- def FormatSize(size):
- # 递归实现,精确为最大单位值 + 小数点后三位
- def formatsize(integer, remainder, level):
- if integer >= 1024:
- remainder = integer % 1024
- integer //= 1024
- level += 1
- return formatsize(integer, remainder, level)
- else:
- return integer, remainder, level
- units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
- integer, remainder, level = formatsize(size, 0, 0)
- if level + 1 > len(units):
- level = -1
- return ('{}.{:>03d} {}'.format(integer, remainder, units[level]))
- # 转换时间
- def get_time(filetime):
- # convert a windows FILETIME to a python datetime
- # https://stackoverflow.com/questions/39481221/convert-datetime-back-to-windows-64-bit-filetime
- WINDOWS_TICKS = int(1 / 10 ** -7) # 10,000,000 (100 nanoseconds or .1 microseconds)
- WINDOWS_EPOCH = datetime.datetime.strptime('1601-01-01 00:00:00', '%Y-%m-%d %H:%M:%S')
- POSIX_EPOCH = datetime.datetime.strptime('1970-01-01 00:00:00', '%Y-%m-%d %H:%M:%S')
- EPOCH_DIFF = (POSIX_EPOCH - WINDOWS_EPOCH).total_seconds() # 11644473600.0
- WINDOWS_TICKS_TO_POSIX_EPOCH = EPOCH_DIFF * WINDOWS_TICKS # 116444736000000000.0
- """Convert windows filetime winticks to python datetime.datetime."""
- winticks = struct.unpack('<Q', filetime)[0]
- microsecs = (winticks - WINDOWS_TICKS_TO_POSIX_EPOCH) / WINDOWS_TICKS
- return datetime.datetime.fromtimestamp(microsecs).strftime('%Y-%m-%d %H:%M:%S')
- class Everything:
- # defines 定义参看Everything.h
- EVERYTHING_REQUEST_FILE_NAME = 0x00000001
- EVERYTHING_REQUEST_PATH = 0x00000002
- EVERYTHING_REQUEST_SIZE = 0x00000010
- EVERYTHING_REQUEST_DATE_MODIFIED = 0x00000040
- EVERYTHING_SORT_SIZE_DESCENDING = 6
- def __init__(self):
- # dll imports
- pwd = os.path.dirname(__file__)
- if platform.architecture()[0] == '32bit':
- self.everything_dll = ctypes.WinDLL(os.path.join(pwd, "Everything32.dll"))
- else:
- self.everything_dll = ctypes.WinDLL(os.path.join(pwd, "Everything64.dll"))
- # everything_dll = ctypes.WinDLL(r"E:\\PYProject\\pyqt5\\everything\\Everything64.dll")
- self.everything_dll.Everything_GetResultDateModified.argtypes = [ctypes.c_int,
- ctypes.POINTER(ctypes.c_ulonglong)]
- self.everything_dll.Everything_GetResultSize.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_ulonglong)]
- self.everything_dll.Everything_GetResultFileNameW.argtypes = [ctypes.c_int]
- self.everything_dll.Everything_GetResultFileNameW.restype = ctypes.c_wchar_p
- # 关键词搜索
- def searchfile(self, bookName):
- recom = re.compile(r'[《》::、;.,,;—— -()()【】\'\"]')
- keyword = recom.sub(' ', bookName).strip()
- if len(keyword) < 1:
- return
- # 文件大小倒序
- self.everything_dll.Everything_SetSort(self.EVERYTHING_SORT_SIZE_DESCENDING)
- self.everything_dll.Everything_SetSearchW(keyword)
- self.everything_dll.Everything_SetRequestFlags(
- self.EVERYTHING_REQUEST_FILE_NAME | self.EVERYTHING_REQUEST_PATH | self.EVERYTHING_REQUEST_SIZE | self.EVERYTHING_REQUEST_DATE_MODIFIED)
- # execute the query
- self.everything_dll.Everything_QueryW(1)
- # get the number of results
- num_results = self.everything_dll.Everything_GetNumResults()
- # show the number of results
- result = "\nResult Count: {}\n".format(num_results)
- print(keyword, result)
- # create buffers
- file_name = ctypes.create_unicode_buffer(260)
- file_modi = ctypes.c_ulonglong(1)
- file_size = ctypes.c_ulonglong(1)
- # show results
- results = [] # 创建一个空列表来保存所有结果
- for i in range(num_results):
- self.everything_dll.Everything_GetResultFullPathNameW(i, file_name, 260)
- self.everything_dll.Everything_GetResultDateModified(i, file_modi)
- self.everything_dll.Everything_GetResultSize(i, file_size)
- filepath = ctypes.wstring_at(file_name)
- if filepath.endswith('.lnk') or filepath.endswith('.txt'):
- continue
- # 计算文件crc32,格式化为0x1122AAFF
- filecrc = hex(crc32_file(filepath)).upper().replace("0X", "0x")
- filesize = FormatSize(file_size.value)
- modtime = get_time(file_modi)
- # strInfo = "\nFilePath: {}\nSize: {} CRC32:{} modtime:{}".format(filepath, filesize, filecrc, modtime)
- # print(strInfo)
- # 创建一个字典包含文件的所有相关信息
- file_info = {
- "file_name": os.path.basename(filepath),
- "file_path": os.path.dirname(filepath),
- "file_size": filesize,
- "modified_time": modtime
- }
- results.append(file_info) # 将字典添加到结果列表中
- return results
- if __name__ == "__main__":
- everythine = Everything()
- everythine.searchfile("科大讯飞")
|