跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

Python怎么压缩文件_zipfile模块打包与解压ZIP压缩包

zipfile.ZipFile()写入必须用'w'或'a'模式,'r'不支持写入;'a'仅对已存在ZIP追加,否则等效'w';需调用close()或with语句;路径须用relpath+arcname转相对路径;中文名需注意编码兼容性;大文件会内存暴涨。 zipfile.ZipFile() 写入模式选错导致压缩包为空 用
zipfile.ZipFile()
创建 ZIP 文件时,
'w'
和
'a'
模式行为差异很大:选
'w'
会清空已有文件并重建;选
'a'
才能追加,但若目标不存在,它也会新建——看似一样,实则底层逻辑不同。更关键的是,如果误用
'r'
模式打开再写,直接抛
ValueError: ZIP does not support writing mode 'r'
。 写新包一律用
'w'
,哪怕只是加一个文件 想往已有 ZIP 里追加?Python 标准库不支持原地追加 ——
'a'
只在文件完全不存在时等效于
'w'
,存在时才真追加;但一旦 ZIP 已有内容,
'a'
会尝试读取目录结构,若损坏或非标准格式就失败 务必调用
.close()
或用
with
语句,否则文件句柄未释放,压缩包可能写入不全、体积为 0 os.walk() 遍历路径传给 write() 时路径错乱 常见错误是把
os.walk()
返回的
root
+
filename
直接喂给
ZipFile.write()
,结果压缩包里出现完整绝对路径(如
/home/user/docs/report.txt
),解压后层层嵌套。ZIP 规范要求内部路径是相对的,
write()
默认保留传入路径的层级。 用
arcname
参数重写归档内路径:
zf.write(full_path, arcname=rel_path)
计算
rel_path
推荐用
os.path.relpath(full_path, start=base_dir)
,其中
base_dir
是你希望压缩包根目录对应的实际路径 别依赖
os.path.basename()
拼接 —— 它只取最后一级,丢失中间目录结构 注意 Windows 路径分隔符:传入
arcname
时统一用
/
(ZIP 标准),
zipfile
内部会处理兼容性 中文文件名乱码或解压失败 ZIP 本身没强制规定编码,Windows 默认用 GBK,macOS/Linux 默认 UTF-8。Python 3 的
zipfile
在读写时默认按 UTF-8 解析文件名,但老压缩包可能是 GBK 编码,直接
namelist()
就返回乱码,
extractall()
则可能抛
UnicodeDecodeError
。 读取未知来源 ZIP 时,先试
ZipFile.namelist()
;若报错或内容异常,改用
ZipFile.filelist
获取原始
ZipInfo
对象,手动 decode:
info.filename.encode('cp437').decode('gbk')
写入含中文路径的文件,确保源字符串是 Unicode(Python 3 默认),
zipfile
会自动 UTF-8 编码写入 —— 但 Windows 资源管理器可能不认,需额外兼容 跨平台分发 ZIP?优先用
shutil.make_archive()
,它内部对中文更鲁棒;或用第三方库如
pyminizip
显式指定编码 大文件压缩内存暴涨或卡死
ZipFile.write()
默认把整个文件读进内存再压缩,遇到几百 MB 的日志或视频,Python 进程 RSS 瞬间翻倍,还可能触发系统 OOM Killer。这不是 bug,是设计使然 —— 它没流式写入接口。 Python 3.14.3 微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。 下载 立即学习 “ Python免费学习笔记(深入) ”; 小文件(write() 没问题 大文件必须分块读写:用
ZipFile.writestr()
+ 自己控制
zlib.compress()
流,但要手算 ZIP 头和校验和,极不推荐 务实方案是绕过
zipfile
:调用系统命令
subprocess.run(['zip', '-r', 'out.zip', 'dir/'])
,或用
shutil.make_archive()
(底层调用系统 zip 或纯 Python 实现,取决于平台) 注意
shutil.make_archive()
的
format='zip'
在某些旧版 Python 中不支持
arcname
定制,需确认版本 ≥3.7 真正麻烦的不是语法,是 ZIP 规范和操作系统实现之间的缝隙——比如 macOS 的 Archive Utility 对 ZIP64 支持不全,而 Python 默认超过 2GB 就切 ZIP64;又比如有些嵌入式设备解压器只认传统 ZIP,不认数据描述符。这些边界情况,光看文档根本踩不到,得靠实际压一压、解一解才知道。

相关文章