基于扩展名列表在文件树中查找文件问题求助
问题诊断与修复方案
我帮你排查了代码里的几个关键问题,这就是你始终匹配不到文件的原因,咱们逐个解决:
1. 扩展名读取时带了换行符
你用readlines()读取CxExt.txt的时候,每一行末尾都会带着换行符\n——比如文件里写的是.py,读出来就变成了.py\n。这样glob去匹配的时候,实际文件的扩展名是.py,自然找不到任何结果。
修复:读取每行时用strip()去掉首尾的空白(包括换行符),顺便过滤掉空行:
with open('CxExt.txt') as fp: extensions = [line.strip() for line in fp if line.strip()]
2. 路径拼接方式错误
你直接用字符串拼路径:working_folder + '**/' + ext,如果working_folder末尾没有路径分隔符(比如/或\),会生成类似test**/.py的畸形路径,glob根本没法正确解析。
修复:用pathlib.Path来安全拼接路径(比os.path.join更直观):
from pathlib import Path working_path = Path(working_folder) for ext in extensions: # 匹配所有子目录下扩展名为ext的文件 results = list(working_path.rglob(f"*{ext}")) print(f"{len(results)} results for {working_path}/**/*{ext}") files_to_zip.extend(results) # 直接把结果列表加进去,比循环append高效
3. 重复且错误的文件匹配逻辑
你前面已经用glob/rglob找过所有文件了,后面又循环os.listdir(working_folder),这里有两个大坑:
os.listdir只返回当前目录的文件名,子目录里的文件根本不会被处理- 这里还有个笔误:
files_to_zip.append(file)应该是files_to_zip.append(os.path.join(working_folder, f)),不然你只添加了文件名,没有路径,写入zip时会报错 - 这段逻辑还会重复添加文件,导致压缩包里出现重复内容
修复:直接删掉这段冗余的循环,只保留前面的glob/rglob匹配逻辑就够了。
4. Zip写入丢失目录结构
你用os.path.basename(z)作为zip内的文件名,会把所有子目录的文件都放到压缩包根目录,原有的目录结构全丢了。如果想保留结构,用相对路径就行:
# 计算文件相对于working_folder的相对路径 relative_path = os.path.relpath(z, working_folder) ZipFile.write(z, relative_path, compress_type=zipfile.ZIP_DEFLATED)
完整修复后的代码
import sys import os import zipfile from pathlib import Path def main(): # 先校验参数是否正确 if len(sys.argv) != 3: print("用法:python script.py <目标文件夹> <压缩包名称>") sys.exit(1) working_folder = sys.argv[1] zip_name = sys.argv[2] # 读取扩展名,处理换行和空行 extensions = [] with open('CxExt.txt') as fp: extensions = [line.strip() for line in fp if line.strip()] if not extensions: print("CxExt.txt里没有有效的扩展名") sys.exit(1) # 查找所有匹配的文件 files_to_zip = [] working_path = Path(working_folder) for ext in extensions: results = list(working_path.rglob(f"*{ext}")) print(f"找到 {len(results)} 个匹配 {ext} 的文件") files_to_zip.extend(results) if len(files_to_zip) == 0: print("没有找到任何匹配的文件") sys.exit() # 创建压缩包,用with语句自动关闭文件 with zipfile.ZipFile(zip_name, "w") as zip_file: for file_path in files_to_zip: relative_path = os.path.relpath(file_path, working_folder) zip_file.write(file_path, relative_path, compress_type=zipfile.ZIP_DEFLATED) print(f"压缩包 {zip_name} 已成功创建!") if __name__ == "__main__": main()
额外小建议
- 可以加个检查,确认传入的
working_folder确实存在,避免报错 - 用
with语句管理ZipFile,确保文件会被正确关闭,不会出现资源泄漏 - 用
extend代替循环append添加列表元素,代码更简洁效率也更高
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

