如何用Python实现比Windows搜索更快的文件搜索?求助提速方案
提升Python文件搜索速度的几种方案
我来帮你搞定这个文件搜索提速的问题!你之前用os.walk()慢得离谱,scandir.walk()只和Windows搜索打平,还碰到faster_than_walk安装失败的坑,下面给你几个实用的优化方向:
一、优化现有scandir代码
你的现有代码其实还有不少优化空间,减少重复计算和不必要的操作就能显著提升速度:
import fnmatch import os import shutil import getpass import scandir import re # 提前构建固定路径,避免循环内重复拼接 usern = getpass.getuser() target_dir = os.path.join('C:\\Users', usern, 'Desktop', 'fetchy') # 确保目标目录存在,避免copy时抛出异常 os.makedirs(target_dir, exist_ok=True) rootPath = input('Please enter the location: ') pattern = input('Please enter resto ID: ') + "_*" # 预编译fnmatch对应的正则表达式,减少每次匹配的转换开销 match_regex = re.compile(fnmatch.translate(pattern)) for root, dirs, files in scandir.walk(rootPath): # 直接遍历scandir返回的DirEntry对象,比单独处理文件名更高效 for entry in files: if match_regex.match(entry.name): full_path = entry.path # DirEntry自带完整路径,不用手动join print(full_path) shutil.copy(full_path, target_dir) print('Done')
优化点说明:
- 提前构建目标目录并确保存在,避免循环内重复执行路径拼接和目录检查
- 预编译匹配规则:fnmatch本质是转成正则表达式,预编译能节省重复转换的时间
- 利用
DirEntry对象的path属性:scandir返回的文件对象已经缓存了完整路径,比手动os.path.join更高效
二、直接调用Windows原生API(极致速度方案)
Windows的文件搜索底层依赖FindFirstFileEx等原生API,用pywin32库直接调用这些API可以跳过Python层的封装开销,速度会比scandir更快:
首先安装pywin32:
pip install pywin32
然后用下面的代码实现递归搜索:
import os import shutil import getpass import win32file import fnmatch usern = getpass.getuser() target_dir = os.path.join('C:\\Users', usern, 'Desktop', 'fetchy') os.makedirs(target_dir, exist_ok=True) rootPath = input('Please enter the location: ') pattern = input('Please enter resto ID: ') + "_*" def recursive_search(root): # 遍历当前目录下的所有项 hFind, data = win32file.FindFirstFile(os.path.join(root, "*")) while True: item_name = data.cFileName if item_name not in ['.', '..']: full_path = os.path.join(root, item_name) # 判断是否为目录,是则递归搜索 if win32file.GetFileAttributes(full_path) & win32file.FILE_ATTRIBUTE_DIRECTORY: # 可在这里跳过系统目录(如回收站、系统卷信息)进一步提速 if item_name not in ['$RECYCLE.BIN', 'System Volume Information']: yield from recursive_search(full_path) else: # 匹配文件规则 if fnmatch.fnmatch(item_name, pattern): yield full_path # 遍历下一个文件 try: data = win32file.FindNextFile(hFind) except win32file.error: break win32file.FindClose(hFind) for file_path in recursive_search(rootPath): print(file_path) shutil.copy(file_path, target_dir) print('Done')
优势:
- 直接调用Windows底层API,减少Python封装带来的额外开销
- 可灵活跳过不需要的系统目录,进一步压缩搜索时间
三、解决faster_than_walk的安装问题
你安装faster_than_walk失败,大概率是因为缺少C编译环境(这个包是C扩展),解决方法如下:
- 安装Visual Studio Build Tools,勾选“C++ build tools”组件(包含MSVC编译器、Windows SDK)
- 或者找对应Python3.7 32位的预编译轮子(.whl文件),直接用
pip install 文件名.whl安装
成功安装后,用法和os.walk几乎一致:
import faster_than_walk for root, dirs, files in faster_than_walk.walk(rootPath): # 后续逻辑和你原来的代码一致 for filename in fnmatch.filter(files, pattern): print(os.path.join(root, filename)) shutil.copy(os.path.join(root, filename), target_dir)
总结
如果不想折腾编译环境,优先用优化后的scandir代码,已经能比原来的版本快不少;如果追求极致速度,直接用Windows API调用的方案;如果一定要用faster_than_walk,先解决编译环境的问题。
内容的提问来源于stack exchange,提问作者Gokkul
相关产品推荐
相关产品推荐

