Watch at Ease看见世界,读懂生活。

科技 · 实用指南

Python报BadZipFile?分清ZIP结构、CRC与预期文件

PK开头、文件列表正常和完整性检查通过,回答的是不同问题。选择修复办法前先保留原文件。

原创编辑插画:ZIP结构、CRC与预期内容需要分别检查。
原创编辑插画:ZIP结构、CRC与预期内容需要分别检查。 Watch at Ease

Python报BadZipFile: File is not a zip file时,先保存准确输入与完整报错。这条信息本身不能证明改扩展名、删缓存或截断字节就能找回预期压缩包。

分三关检查:Python能否解析结构,能否读取成员且未检出CRC错误,以及包内是否包含这次交付要求的文件。我们实际做了五个小型合成测试,说明这些结论不能互相替代。

1. 保留准确输入,记录失败发生在哪一步

记录实际路径、字节数、SHA-256、Python版本和完整异常。原件保持不变,用副本排查。本地计算的摘要只能标识字节;只有与针对同一文件、独立可信的参考值比较,才有来源验证意义。

下载文件应核对授权来源与目标版本,确认保存的不是错误页或登录页。自己生成ZIP时,要等写入端关闭再让读取端打开;Python文档说明关闭时会写入必要记录。不要用w模式打开原件,它会截断文件。

2. 先解析结构,再考虑读取全部正文

对来源已知、体积适当的小样本,先调用zipfile.is_zipfile(path),再用with zipfile.ZipFile(path, "r") as z打开并查看z.infolist()。记录名称、file_size、compress_size和compress_type。构造对象就失败时,不能声称已成功列出成员。PKWARE要求结束记录,前两个字母不足以证明目录完整。

核对来源和资源范围后,才在同一上下文中调用z.testzip()。它读取成员,返回首个坏文件名,所查项目通过时返回None。异常必须记为未解决,不能吞掉后当成成功。声明大小只能帮助判断范围,并非强制资源边界;大型或不可信压缩包需要有硬性限制的隔离处理。

3. 对照五个实际测试结果

我们在Python3.12.14中生成很小的BytesIO样本,没有执行解压。正常136字节ZIP列出report.txt,testzip()返回None。删除22字节结束记录后,114字节样本仍以PK开头,但is_zipfile()为False,构造ZipFile时报BadZipFile。

只翻转一个未压缩正文的字节、保留原CRC,文件仍为136字节;is_zipfile()为True,也能列出report.txt,但testzip()返回report.txt。合法22字节空ZIP返回True和None,列表却为空。20字节HTML样本不能识别为ZIP。这些对照展示不同失败阶段,并未诊断你的文件,也未测试全部ZIP功能。

4. 针对已证实原因修复,再验收交付

错误格式或未下载完整时,通过正常授权渠道另存一份,再核对同一文件的可信参考。生成端未收尾时,应重新生成并正确关闭。如果异常指出压缩或加密功能不受支持,先查当前读取器能力,不要仅凭异常断定字节损坏;Python zipfile不处理分卷ZIP。

保留文件摘要、结构结果、CRC结果、预期成员名称及最终应用测试。CRC通过不证明发布者真实、内容安全或必需文件齐全。少了预期文件,即使testzip()返回None也要停止验收。不要对唯一原件套用通用的签名截断补丁:能打开并不等于缺失正文被找回。

原创编辑插画:Python3.12.14小型合成样本的实际结果。
原创编辑插画:Python3.12.14小型合成样本的实际结果。 Watch at Ease