Python解压同名zip文件内容不同时触发PermissionError报错如何解决
报错根因
- 代码逻辑存在严重的资源泄漏问题:仅在目标文件不存在的else分支使用
with托管文件句柄、执行文件写入操作,目标文件已存在的if分支仅打开了source、target两个文件对象,既没有执行写入逻辑,也没有关闭文件,Windows系统下残留的文件锁直接触发PermissionError: [WinError 32]报错 - 代码缺少必要的初始化逻辑:
counts变量未定义初始值,运行时会直接抛出NameError - 未实现需求中的内容校验逻辑:当前代码没有对同名zip包的内部文件做一致性校验,不符合业务要求
修复后代码
import zipfile import os import shutil def unzip_validate(file_path, intermediary_path, counts=0): # 校验同名zip内容一致性逻辑 zip_filename = os.path.basename(file_path) # 读取当前zip所有txt文件的CRC值 current_zip = zipfile.ZipFile(file_path) current_crc_map = {} for file in current_zip.filelist: if file.filename.endswith(".txt"): current_crc_map[os.path.basename(file.filename)] = file.CRC # 检查是否有已解压的同zip来源的记录,比对CRC crc_record_path = os.path.join(intermediary_path, f".{zip_filename}_crc") if os.path.exists(crc_record_path): # 读取历史CRC记录 with open(crc_record_path, 'r', encoding='utf-8') as f: history_crc = {k:int(v) for k,v in [line.strip().split(":") for line in f.readlines()]} # 比对CRC if current_crc_map != history_crc: raise Exception("同名zip包内部文件内容不一致,下载终止") else: # 保存CRC记录 with open(crc_record_path, 'w', encoding='utf-8') as f: for filename, crc in current_crc_map.items(): f.write(f"{filename}:{crc}\n") # 执行解压逻辑 for file in current_zip.filelist: if not file.filename.endswith(".txt"): continue base_filename = os.path.basename(file.filename) if base_filename in os.listdir(intermediary_path): # 重命名重复文件 name_part, ext_part = os.path.splitext(base_filename) target_path = os.path.join(intermediary_path, f"{name_part}_{counts}{ext_part}") counts += 1 else: target_path = os.path.join(intermediary_path, base_filename) # 统一用with托管文件句柄,自动释放 with current_zip.open(file) as source, open(target_path, "wb") as target: shutil.copyfileobj(source, target) current_zip.close() # 调用示例 # unzip_validate("你的zip文件路径", "解压中转路径")
修复说明
- 统一用
with语句托管所有文件对象,操作完成后自动释放句柄,彻底解决文件锁残留导致的权限报错 - 新增同名zip包内容一致性校验逻辑:通过zip内文件自带的CRC32校验值做内容比对,完全一致才允许解压,不一致直接抛出异常终止流程
- 修复原代码中重复文件分支未执行写入的逻辑错误,补全了
counts变量的初始化逻辑
内容的提问来源于stack exchange,提问作者halberdier15
相关产品推荐
相关产品推荐

