zipfile可读取ZIP文件元数据:通过ZipFile.infolist()或getinfo()获取ZipInfo对象,含filename、file_size、compress_size、date_time等字段,需手动转换date_time为datetime类型。

用 zipfile 读取 ZIP 文件内文件的元数据
Python 标准库 zipfile 可以直接获取 ZIP 包中每个文件的属性,但注意:它不提供修改时间以外的完整系统属性(如权限、所有者),且 st_mtime 等字段需手动从 ZipInfo 的 date_time 元组转换。
-
ZipInfo.filename是相对路径,不含驱动器或根目录,注意处理重复名或目录项(filename.endswith("/")) -
ZipInfo.file_size和ZipInfo.compress_size分别对应原始大小和压缩后大小,可用于计算压缩率 -
ZipInfo.date_time是形如(year, month, day, hour, minute, second)的元组,需转为datetime才能参与比较或格式化 - ZIP 规范不存储 Unix 权限位,
ZipInfo.external_attr低 16 位可能含部分 mode 信息(如0o100644 & 0xFFFF),但不可靠,不同打包工具写入方式不一致
用 tarfile 获取 TAR/GZ/BZ2 中文件的完整属性
tarfile 比 zipfile 更接近真实文件系统语义,能读取 uid/gid/mode/mtime —— 但前提是源 TAR 包在创建时保留了这些信息(例如用 tar -czf 默认保留,而 tar --format=ustar 才保证 POSIX 兼容)。
-
TarInfo.name同样是相对路径,但支持硬链接、软链接等特殊类型(TarInfo.type可判别) -
TarInfo.mode是八进制整数(如0o100644),可直接用stat.filemode()转成-rw-r--r--字符串 -
TarInfo.mtime是秒级时间戳,比 ZIP 的date_time更易处理;TarInfo.uid/TarInfo.gid在跨平台解包时可能丢失,但读取时仍存在 - 对
.tar.gz或.tar.bz2,打开时必须指定mode="r:gz"或mode="r:bz2",否则会报OSError: Invalid argument
遇到 BadZipFile 或 TarError 怎么快速定位问题
不是所有带 .zip/.tar 后缀的文件都合规 —— 常见原因包括:网络传输中断导致截断、加密 ZIP(zipfile 不支持密码解密)、损坏的 gzip 流头、或 TAR 使用了非标准扩展(如 GNU longlink)。
- 先用
file xxx.zip(Linux/macOS)或certutil -hashfile xxx.zip SHA1(Windows)确认文件完整性 - 对 ZIP,尝试
zipfile.ZipFile(xxx).testzip(),返回第一个损坏文件名,或None表示无损坏 - 对 TAR,捕获
tarfile.ReadError并检查e.args[0]是否含"truncated"或"invalid header" - 若需跳过损坏条目继续读取,ZIP 不支持“容错遍历”,TAR 可设
errorlevel=0(但会丢失部分元数据)
提取属性时要不要解压到磁盘
完全不需要。所有属性读取均可在不解压情况下完成 —— zipfile 和 tarfile 都支持只读元数据模式,内存占用极小,且避免了临时文件清理问题。
立即学习“Python免费学习笔记(深入)”;
- 误调用
extractall()或extract()会导致实际写入文件,尤其当 ZIP 内含../路径时可能引发路径遍历风险 - 想验证某文件是否存在?用
namelist()(ZIP)或getnames()(TAR),而非遍历后os.path.exists() - 如果后续要读文件内容,用
open()方法(ZIP 返回ZipExtFile,TAR 返回TarFile.fileobj),它们都是类文件对象,支持.read(),无需落地
external_attr 解析逻辑和 TAR 的 encoding 参数 —— 中文路径在某些 TAR 包里会因编码不匹配变成乱码,此时需显式传入 encoding="utf-8" 或 encoding="gbk"。


















