如何高效筛选文件名前缀大于指定ID的海量文件?
优化方案
1. 降低字符串处理开销:替换正则分割为普通字符串分割
原代码用re.split("\.",filename)[0]提取前缀,可直接换成filename.split('.')[0]——因为文件名格式固定为数字.txt,普通字符串分割比正则表达式的运行开销小得多,能节省大量循环内的处理时间。
2. 先过滤排序再批量处理(推荐)
如果目标目录没有子目录,直接用os.listdir获取文件列表,先筛选出.txt后缀的文件,再提取前缀数字并排序,通过二分查找快速定位到第一个大于last_processed_id的文件位置,后续仅处理该位置之后的文件:
import os import bisect directory = "/你的目标目录路径" last_processed_id = 1000 # 从数据库获取 # 筛选所有txt格式文件 txt_files = [f for f in os.listdir(directory) if f.endswith(".txt")] # 提取有效前缀数字并与文件名配对,跳过格式异常的文件 file_id_pairs = [] for filename in txt_files: try: prefix = int(filename.split('.')[0]) file_id_pairs.append((prefix, filename)) except ValueError: continue # 按前缀数字排序 file_id_pairs.sort() # 提取前缀数字列表用于二分查找 prefix_list = [pair[0] for pair in file_id_pairs] # 找到第一个大于last_processed_id的文件索引 start_idx = bisect.bisect_right(prefix_list, last_processed_id) # 批量处理目标文件 for prefix, filename in file_id_pairs[start_idx:]: full_path = os.path.join(directory, filename) # <执行文件处理逻辑>
这种方式的优势:
- 仅处理符合格式的目标文件
- 排序后通过二分查找快速定位起始点,避免逐个判断每个文件
- 字符串转数字的操作集中在排序前,后续直接处理目标文件
3. 用glob缩小初始文件范围(适用于已知数字位数的场景)
如果知道last_processed_id的位数范围,比如last_processed_id = 999,要处理1000及以上的文件,可直接用glob匹配对应位数的文件,提前过滤掉大部分不需要处理的内容:
import glob directory = "/你的目标目录路径" last_processed_id = 999 # 匹配4位及以上数字的txt文件 target_files = glob.glob(os.path.join(directory, "[1-9][0-9][0-9][0-9]*.txt")) for filename in target_files: prefix = int(os.path.basename(filename).split('.')[0]) if prefix > last_processed_id: # <执行文件处理逻辑>
这种方式能大幅减少后续需要判断的文件数量,但缺点是需要提前明确数字的位数范围,灵活性有限。
4. 跳过不必要的子目录遍历
如果不需要处理子目录中的文件,在os.walk遍历过程中清空dirs列表,避免无意义的子目录扫描:
for root, dirs, files in os.walk(directory): # 清空dirs,终止子目录遍历 dirs.clear() # 后续文件处理逻辑...
内容的提问来源于stack exchange,提问作者abinitio
相关产品推荐
相关产品推荐

