Python zipfile 只借助内存进行压缩与解压缩
Python zipfile 模块压缩与解压缩通常是对物理磁盘文件进行操作,比如参照官方的例子,生成压缩文件的代码是
前面顺便也是熟悉一下 zipfile 模块的常见用法,但有时候我们可能从数据库中,从网络上收到的是字节数据,希望直接处理字节的压缩解压缩,而不借助于中间的磁盘文件,因为通过磁盘文件来处理必须进行善后处理以及可能的资源的竞争,在内存宽裕的情况下效率也是个问题。
在 Java 中处理内存数据经常用到的是
只需调用 myzip.writestr(filename, original_content) 方法就行,数据可以是字符串或 bytes,filename 部分还可以有目录结构
不指定 zipfile.ZIP_DEFLATED 的话不会对数据进行压缩,只是存储。
上面产生的
如果解压一下,会看到目录结构与我们设想的一致,三个文件
这里的代码使用到了递归一直罗列压缩包中的条目,压缩包中文件的内容可用
链接:
永久链接 https://yanbin.blog/python-zipfile-compress-decompress-in-memory/, 来自 隔叶黄莺 Yanbin's Blog
[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。
with zipfile.ZipFile('spam.zip', 'w') as myzip:这样就生成了一个包含两个文件的压缩包 spam.zip, 相当于命令
myzip.write('eggs.txt')
myzip.write('beef.txt')
zip spam.zip egges.txt beef.txt 的效果。用 unzip -l spam.zip 命令就能看到其中的两个文件。相应的解压缩的代码如下with zipfile.ZipFile('spam.zip', 'r') as myzip:同样是把压缩包 spam.zip 解压缩文件到当前目录中,相当于命令
print(myzip.filelist()) # 可获得压缩包中的文件列表信息
myzip.extractall()
unzip spam.zip 的效果。前面顺便也是熟悉一下 zipfile 模块的常见用法,但有时候我们可能从数据库中,从网络上收到的是字节数据,希望直接处理字节的压缩解压缩,而不借助于中间的磁盘文件,因为通过磁盘文件来处理必须进行善后处理以及可能的资源的竞争,在内存宽裕的情况下效率也是个问题。
在 Java 中处理内存数据经常用到的是
ByteArrayInputStream 和 ByteArrayOutputStream,而在 Python 中承担相同角色的就是 io.BytesIO()。下面来看如何使用它在内存进行双向操作通过内存生成压缩文件字节内容
本例放到压缩包中的内容是字节,生成的压缩包也是字节表现形式 1import zipfile
2import io
3
4file = io.BytesIO()
5with zipfile.ZipFile(file, 'w', zipfile.ZIP_DEFLATED) as myzip:
6 myzip.writestr('eggs.txt', 'Here are eggs')
7 myzip.writestr('beef.txt', b'I am beef')
8 myzip.writestr('veggs/pickle.txt', 'pickles')
9
10zip_data = file.getvalue()
11
12with open('spam.zip', 'wb') as zipfile:
13 zipfile.write(zip_data) 只需调用 myzip.writestr(filename, original_content) 方法就行,数据可以是字符串或 bytes,filename 部分还可以有目录结构
不指定 zipfile.ZIP_DEFLATED 的话不会对数据进行压缩,只是存储。
上面产生的
zip_data 就是压缩包的字节内容,我们把 zip_data 字节数据保存到 spam.zip 压缩文件,然后用 unzip -l spam.zip 命令查看1$ unzip -l spam.zip
2Archive: spam.zip
3 Length Date Time Name
4--------- ---------- ----- ----
5 13 10-13-2021 22:17 eggs.txt
6 9 10-13-2021 22:17 beef.txt
7 7 10-13-2021 22:17 veggs/pickle.txt
8--------- -------
9 29 3 files如果解压一下,会看到目录结构与我们设想的一致,三个文件
eggs.txt, beef.txt 和 veggs/picle.txt 中的内容分别是字符符 Here are eggs, I am beef, 和 pickles。解压缩 zip 字节内容为字节数据
现在我们直接使用上一步产生的 spam.zip 文件内容,首先假定输入为字节数据,然后窥探其中每一个条目的文件信息与内容 1import zipfile
2import io
3import os
4
5
6def read_zipfiles(path, folder=''):
7 for member in path.iterdir():
8 filename = os.path.join(folder, member.name)
9 if member.is_file():
10 print(filename, ':', member.read_text()) # member.read_bytes()
11 else:
12 read_zipfiles(member, filename)
13
14
15with open('spam.zip', 'rb') as myzip:
16 zip_data = myzip.read()
17
18
19with zipfile.ZipFile(io.BytesIO(zip_data)) as zip_file:
20 read_zipfiles(zipfile.Path(zip_file))这里的代码使用到了递归一直罗列压缩包中的条目,压缩包中文件的内容可用
read_text() 和 read_bytes() 分别读出为文本或字节。这是此代码执行后的输出$ python tt.py如果我们明确的知道(比如约定了)压缩包中不会有目录层次,则可不用递归来处理。
eggs.txt : Here are eggs
beef.txt : I am beef
veggs/pickle.txt : pickles
链接:
永久链接 https://yanbin.blog/python-zipfile-compress-decompress-in-memory/, 来自 隔叶黄莺 Yanbin's Blog
[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。