1. 压缩归档
如果是用于归档文件,那我们最好的选择就是使用压缩工具,python的标准库自带zipfile和tarfile用来压缩归档文件,还有gzip用来为单一文件进行压缩,另外github上还有一个归档为rar的工具rarfile.
1.1. zipfile
zip文件格式由三个部分组成:压缩源文件数据区+压缩源文件目录区+压缩源文件目录结束标志
压缩源文件数据区
在这个数据区中每一个压缩的源文件/目录都是一条记录,记录的格式如下: [文件头+ 文件数据 + 数据描述符]
- 文件头结构
组成 | 长度 |
---|---|
文件头标记 | 4 bytes (0x04034b50) |
解压文件所需 pkware 版本 | 2 bytes |
全局方式位标记 | 2 bytes |
压缩方式 | 2 bytes |
最后修改文件时间 | 2 bytes |
最后修改文件日期 | 2 bytes |
CRC-32校验 | 4 bytes |
压缩后尺寸 | 4 bytes |
未压缩尺寸 | 4 bytes |
文件名长度 | 2 bytes |
扩展记录长度 | 2 bytes |
文件名 | (不定长度) |
扩展字段 | (不定长度) |
文件数据
数据描述符
组成 | 长度 |
---|---|
CRC-32校验 | 4 bytes |
压缩后尺寸 | 4 bytes |
未压缩尺寸 | 4 bytes |
这个数据描述符只在全局方式位标记的第3位设为1时才存在,紧接在压缩数据的最后一个字节后。这个数据描述符只用在不能对输出的 ZIP 文件进行检索时使用。例如:在一个不能检索的驱动器(如:磁带机上)上的 ZIP 文件中。如果是磁盘上的ZIP文件一般没有这个数据描述符。
压缩源文件目录区
在这个数据区中每一条纪录对应在压缩源文件数据区中的一条数据
组成 | 长度 |
---|---|
目录中文件文件头标记 | 4 bytes (0x02014b50) |
压缩使用的pkware 版本 | 2 bytes |
解压文件所需 pkware 版本 | 2 bytes |
全局方式位标记 | 2 bytes |
压缩方式 | 2 bytes |
最后修改文件时间 | 2 bytes |
最后修改文件日期 | 2 bytes |
CRC-32校验 | 4 bytes |
压缩后尺寸 | 4 bytes |
未压缩尺寸 | 4 bytes |
文件名长度 | 2 bytes |
扩展字段长度 | 2 bytes |
文件注释长度 | 2 bytes |
磁盘开始号 | 2 bytes |
内部文件属性 | 2 bytes |
外部文件属性 | 4 bytes |
局部头部偏移量 | 4 bytes |
文件名 | (不定长度) |
扩展字段 | (不定长度) |
文件注释 | (不定长度) |
压缩源文件目录结束标志
组成 | 长度 |
---|---|
目录结束标记 | 4 bytes (0x02014b50) |
当前磁盘编号 | 2 bytes |
目录区开始磁盘编号 | 2 bytes |
本磁盘上纪录总数 | 2 bytes |
目录区中纪录总数 | 2 bytes |
目录区尺寸大小 | 4 bytes |
目录区对第一张磁盘的偏移量 | 4 bytes |
ZIP 文件注释长度 | 2 bytes |
ZIP 文件注释 | (不定长度) |
import zipfile
1.1.1. 创建归档
with zipfile.ZipFile('source/output/笑傲江湖.zip', 'w',zipfile.ZIP_DEFLATED) as f: f.write("source/input/笑傲江湖.txt")
with open("source/input/iris.csv","r") as f: content = f.read()
with zipfile.ZipFile('source/output/iris_str.zip', 'w',zipfile.ZIP_DEFLATED) as f: f.writestr( 'iris_str.csv',content)
在归档大量文件时,我们可以用allowZip64=True
来指定支持超过2Gb的归档
with zipfile.ZipFile('source/output/all_input.zip', 'w',zipfile.ZIP_DEFLATED,allowZip64=True) as f: f.write("source/input/笑傲江湖.txt") f.write("source/input/iris.csv") f.write("source/input/people.json")
1.1.2. 查看压缩文件信息
#查看是不是zip压缩文件 zipfile.is_zipfile("source/output/all_input.zip")
True
# 查看zip中的文件列表 with zipfile.ZipFile('source/output/all_input.zip', 'r',zipfile.ZIP_DEFLATED) as f: print(f.namelist())
['source/input/笑傲江湖.txt', 'source/input/iris.csv', 'source/input/people.json']
# 打开zip中某个文件 with zipfile.ZipFile('source/output/all_input.zip', 'r',zipfile.ZIP_DEFLATED) as f: print(f.open('source/input/people.json').read().decode("utf-8"))
with zipfile.ZipFile('source/output/笑傲江湖.zip', 'w',zipfile.ZIP_DEFLATED) as f: f.write("source/input/笑傲江湖.txt")
0
with zipfile.ZipFile('source/output/笑傲江湖.zip', 'w',zipfile.ZIP_DEFLATED) as f: f.write("source/input/笑傲江湖.txt")
1
with zipfile.ZipFile('source/output/笑傲江湖.zip', 'w',zipfile.ZIP_DEFLATED) as f: f.write("source/input/笑傲江湖.txt")
2
with zipfile.ZipFile('source/output/笑傲江湖.zip', 'w',zipfile.ZIP_DEFLATED) as f: f.write("source/input/笑傲江湖.txt")
3
with zipfile.ZipFile('source/output/笑傲江湖.zip', 'w',zipfile.ZIP_DEFLATED) as f: f.write("source/input/笑傲江湖.txt")
4
with zipfile.ZipFile('source/output/笑傲江湖.zip', 'w',zipfile.ZIP_DEFLATED) as f: f.write("source/input/笑傲江湖.txt")
5
with zipfile.ZipFile('source/output/笑傲江湖.zip', 'w',zipfile.ZIP_DEFLATED) as f: f.write("source/input/笑傲江湖.txt")
6
with zipfile.ZipFile('source/output/笑傲江湖.zip', 'w',zipfile.ZIP_DEFLATED) as f: f.write("source/input/笑傲江湖.txt")
7
with zipfile.ZipFile('source/output/笑傲江湖.zip', 'w',zipfile.ZIP_DEFLATED) as f: f.write("source/input/笑傲江湖.txt")
8
with zipfile.ZipFile('source/output/笑傲江湖.zip', 'w',zipfile.ZIP_DEFLATED) as f: f.write("source/input/笑傲江湖.txt")
9
with open("source/input/iris.csv","r") as f: content = f.read()
0
1.1.3. 解压文件
with open("source/input/iris.csv","r") as f: content = f.read()
1
with open("source/input/iris.csv","r") as f: content = f.read()
2
1.1.4. 密码处理
zipfile只能解压带密码的zip包,并不支持创建加密的zip归档,要使用密码只要像这个样:
with open("source/input/iris.csv","r") as f: content = f.read()
3
即可
1.2. tarfile
tar是linux下是常见的归档格式,常见的后缀有tar,tar.bz,tar.gz三种后缀,分别对应三种不同的压缩算法,
tarfile的归档用法也与zipfile类似,只是接口有些变化
with open("source/input/iris.csv","r") as f: content = f.read()
4
with open("source/input/iris.csv","r") as f: content = f.read()
5
with open("source/input/iris.csv","r") as f: content = f.read()
6
True
with open("source/input/iris.csv","r") as f: content = f.read()
8
with open("source/input/iris.csv","r") as f: content = f.read()
9
with zipfile.ZipFile('source/output/iris_str.zip', 'w',zipfile.ZIP_DEFLATED) as f: f.writestr( 'iris_str.csv',content)
0
['source/input/笑傲江湖.txt', 'source/input/iris.csv', 'source/input/people.json']
with zipfile.ZipFile('source/output/iris_str.zip', 'w',zipfile.ZIP_DEFLATED) as f: f.writestr( 'iris_str.csv',content)
2
with zipfile.ZipFile('source/output/iris_str.zip', 'w',zipfile.ZIP_DEFLATED) as f: f.writestr( 'iris_str.csv',content)
3
with zipfile.ZipFile('source/output/iris_str.zip', 'w',zipfile.ZIP_DEFLATED) as f: f.writestr( 'iris_str.csv',content)
4
with zipfile.ZipFile('source/output/iris_str.zip', 'w',zipfile.ZIP_DEFLATED) as f: f.writestr( 'iris_str.csv',content)
5
如果要结合gz或者bz压缩,那么就不能使用这个类,而要使用tarfile.open(name=None, mode='r', fileobj=None, bufsize=10240, **kwargs)
函数
其中mode=可选的有:
mode | 说明 |
---|---|
'r' or 'r:*' | 使用透明压缩读打开 |
'r:' | 无压缩读打开 |
'r:gz' | gzip压缩读打开 |
'r:bz2' | bzip2压缩读打开 |
'a' or 'a:' | 无需压缩append写打开。如果文件不存在,则创建该文件。 |
'w' or 'w:' | 无压缩写 |
'w:gz' | gzip写打开 |
'w:bz2' | bzip2写打开 |
with zipfile.ZipFile('source/output/iris_str.zip', 'w',zipfile.ZIP_DEFLATED) as f: f.writestr( 'iris_str.csv',content)
6
with zipfile.ZipFile('source/output/iris_str.zip', 'w',zipfile.ZIP_DEFLATED) as f: f.writestr( 'iris_str.csv',content)
7
1.3. rarfile
python标准库并不支持rar格式的归档,但有个rarfile可以通过pip安装,他的接口与zipfile一样,只是不能写只能读
还没有评论,来说两句吧...