Python内存中的zip库
有没有一个Python库,可以在内存中操作zip压缩文件,而不需要使用实际的磁盘文件?
ZipFile库不允许你直接更新压缩文件。唯一的办法似乎是先把压缩文件解压到一个文件夹里,进行修改,然后再从那个文件夹创建一个新的zip文件。我想在不使用磁盘的情况下修改zip文件,因为我会下载这些文件,做一些修改,然后再上传,所以我根本不需要把它们存储在本地。
类似于Java的ZipInputStream/ZipOutputStream的功能就可以了,任何可以避免使用磁盘的接口都可以。
9 个回答
60
来自文章 在Python中内存压缩:
下面是我在2008年5月写的一篇关于在内存中使用Python进行压缩的帖子,因为Posterous要关闭,所以重新发布一下。
我最近发现有一个收费的组件可以在内存中用Python压缩文件。考虑到这应该是免费的,我写了以下代码。这个代码只经过了非常基础的测试,所以如果有人发现错误,请告诉我,我会更新的。
import zipfile
import StringIO
class InMemoryZip(object):
def __init__(self):
# Create the in-memory file-like object
self.in_memory_zip = StringIO.StringIO()
def append(self, filename_in_zip, file_contents):
'''Appends a file with name filename_in_zip and contents of
file_contents to the in-memory zip.'''
# Get a handle to the in-memory zip in append mode
zf = zipfile.ZipFile(self.in_memory_zip, "a", zipfile.ZIP_DEFLATED, False)
# Write the file to the in-memory zip
zf.writestr(filename_in_zip, file_contents)
# Mark the files as having been created on Windows so that
# Unix permissions are not inferred as 0000
for zfile in zf.filelist:
zfile.create_system = 0
return self
def read(self):
'''Returns a string with the contents of the in-memory zip.'''
self.in_memory_zip.seek(0)
return self.in_memory_zip.read()
def writetofile(self, filename):
'''Writes the in-memory zip to a file.'''
f = file(filename, "w")
f.write(self.read())
f.close()
if __name__ == "__main__":
# Run a test
imz = InMemoryZip()
imz.append("test.txt", "Another test").append("test2.txt", "Still another")
imz.writetofile("test.zip")
130
PYTHON 3
import io
import zipfile
zip_buffer = io.BytesIO()
with zipfile.ZipFile(zip_buffer, "a", zipfile.ZIP_DEFLATED, False) as zip_file:
for file_name, data in [('1.txt', io.BytesIO(b'111')),
('2.txt', io.BytesIO(b'222'))]:
zip_file.writestr(file_name, data.getvalue())
with open('C:/1.zip', 'wb') as f:
f.write(zip_buffer.getvalue())
122
根据Python文档的说明:
class zipfile.ZipFile(file[, mode[, compression[, allowZip64]]])
Open a ZIP file, where file can be either a path to a file (a string) or a file-like object.
所以,要在内存中打开文件,只需创建一个类似文件的对象(可以使用BytesIO)。
file_like_object = io.BytesIO(my_zip_data)
zipfile_ob = zipfile.ZipFile(file_like_object)