zipfile
zipfile库提供了对 zip 归档文件的不完整支持,他不能处理 zip 分卷,不支持创建加密 zip 文件(支持解密)。
ZipFile
该库使用 ZipFile()
来构造一个 zip 对象,他支持 with 语句:
Python
class zipfile.ZipFile(
file, # path-like object
mode='r',# r - 读取 w - 写入新文件(如果存在则覆盖) a - 像现有文件中添加 x - 写入新文件(文件存在抛出异常)
compression=ZIP_STORED, # 压缩算法 ZIP_STORED 仅归档 ZIP_DEFLATED (zlib提供) ZIP_BZIP2(bz2提供) ZIP_LZMA(lzma提供) 有些压缩软件并不支持后两个
allowZip64=True, # 是否支持 4G 以上的归档文件
compresslevel=None, # 压缩等级 0~9
strict_timestamps=True, # zip 时间戳精度有问题,仅支持 1980-1-1 ~ 2107-12-31 如果设置为 False 其他时间戳的文件会强制转换为这个时间范围内,默认 True 时间戳外的文件会报错
metadata_encoding=None # 元信息编码
):
pass
最终会返回一个 ZipFile 对象,他代表一个 zip 归档文件,我们操作这个 ZipFile 对象无非就是进行增删改查,最后 ZipFile.close()
即可(如果使用 with 语句不需要我们手动处理它):
ZipFile.namelist()
: 返回按照名称排序的归档成员ZipFile.infolist()
: 返回 zip 文件中的每个成员的 ZipInfo 对象ZipFile.getinfo(name)
: 返回指定文件的 ZipInfo 对象ZipFile.open(name, mode='r')
: 打开 zip 归档文件中的指定文件(open 接口),如果mode='w'
支持写入,需要注意当写入时无法再读写这个 ZipFile 对象直到写入完成ZipFile.read(name)
: 读取指定文件,open()
的 read 接口(如果需要流式读取还是需要 open)ZipFile.write(filename, arcname=None)
: 将名为 filename 的文件写入到 zip 归档文件中,文件名为 arcname(默认为 filename 去除盘符和开头的路径分隔符)。它实际上就是open(filename, 'r')
之后ZipFile.open(arcname).write()
的便捷方法ZipFile.writestr(arcname, data: str|bytes)
: 实际上就是ZipFile.open(arcname).write(data)
的便捷方法ZipFile.extract(member, path=None)
: 从 zip 归档文件中提取一个文件,默认当前目录ZipFile.extractall(path=None)
: 从 zip 归档文件中提取所有文件, 默认当前目录ZipFile.mkdir(zinfo_or_dir)
: 在归档文件内创建一个目录
ZipInfo
上面所有需要指定 zip 归档中文件的地方都可以是一个路径字符串(没有盘符和开头的路径分隔符),例如 open 中的 name、write 中的 arcname 和 extract 中的 member。实际上他们还可以是一个 ZipInfo
对象,这个对象代表 zip 归档中的每个文件,要构造这个对象有两种方法:
ZipInfo.from_file(filename, arcname=None)
: 为文件系统的文件构造一个 ZipInfo 实例,供ZipFile.write()
方法使用将在随后添加到 zip 归档中ZipFile.getinfo()
和ZipFile.infolist()
: 这两个方法都能够返回ZipInfo
对象
Tips
文件夹本身也存在一个 ZipInfo 对象,因此这个对象更像是一个节点对象
ZipInfo
对象包含以下实例:
ZipInfo.is_dir()
: 是否是文件夹ZipInfo.filename
: 归档中的文件名称ZipInfo.compress_size
: 已压缩的文件大小ZipInfo.file_size
: 原始文件的大小
Path
zip 归档可以看作是一个小型的文件系统,Python 使用 pathlib.Path
一样的接口来为 ZipFile 构造一个 Path 对象:
Python
class zipfile.Path(
root, # 可以是 ZipFile 实例,或者 zip 文件路径
at="" # 指定相对路径,默认是根目录,即 root/dir1/file1.txt root/file2.txt
):
pass
Path 暴露出来的接口是 pathlib.Path
的子集:
Path.name
: 路径名称Path.is_dir()
: 是否是文件夹Path.is_file()
: 是否是文件Path.iterdir()
: 迭代文件夹下文件Path.exists()
: 文件/文件夹是否存在Path.suffix
: 文件后缀名Path.stem
: 排除后缀名的路径Path.open(mode='r')
: 打开文件Path.read_text()
: 读取文本文件Path.read_bytes()
: 读取二进制文件
Path 在对 zip 进行读写操作的时候非常有用,他将 zip 当作一个独立的文件系统提供了 pathlib 一样的操作接口,他屏蔽了 zip 和本地系统的区别:
Python
import zipfile
with zipfile.ZipFile("test.zip", "w", compression=zipfile.ZIP_DEFLATED) as zip_file:
path = zipfile.Path(zip_file)
(path / "test1.txt").open("w").write("test1")
(path / "test2.txt").open("w").write("test2")
(path / "inner" / "inner1.txt").open("w").write("inner1")
(path / "inner" / "inner2.txt").open("w").write("inner2")