Python内存中的zip库

124 投票
9 回答
125207 浏览
提问于 2025-04-15 20:32

有没有一个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)

撰写回答