4

有没有办法ZipFile通过传入 zip 文件的文字字节来初始化对象,而不是让它读取文件名?我正在构建一个不需要触摸磁盘的宁静应用程序;它只是打开文件,对其进行一些处理,重新压缩并发送。

4

3 回答 3

6

在对其他答案的评论中,您说您想这样做:

打开一个二进制字符串,就好像它是一个 zip 文件一样。打开它,读/写里面的文件,然后关闭它

您只需执行与其他答案相同的操作,只是创建一个StringIO.StringIO(or cStringIO.StringIOor io.BytesIO) 预先填充了二进制字符串,并在最后提取该字符串。StringIO和朋友为他们的构造函数取一个可选的初始字符串,并getvalue在你完成后有一个提取字符串的方法。文档非常简单,值得一读。

所以,尽可能地接近 alecxe 的答案:

from zipfile import ZipFile
try:
    import cStringIO as StringIO
except ImportError:
    import StringIO

in_memory = StringIO.StringIO(original_zip_data)
zf = ZipFile(in_memory, "a")  

zf.writestr("file.txt", "some text contents")

zf.close()

new_zip_data = in_memory.getvalue()

但是,请注意ZipFile,除了向其附加新文件的特殊情况外,不能真正就地写入 zip 存档。这对于内存中的 zip 存档和磁盘上的存档一样正确。您通常可以通过附加具有相同路径的新文件来避免覆盖存档中的文件,但这通常是一个坏主意(特别是如果您正在创建这些内容以通过 Internet 发送)。

因此,您可能想要做的与您想要修改文件时完全一样:创建一个单独的输出文件,从输入文件中复制您需要的内容,并在进行过程中编写新内容。只是在这种情况下,输入和输出文件都是ZipFile对象包装StringIO对象。

于 2013-09-23T19:54:51.340 回答
2

当然,请改用 (c)StringIO:http://docs.python.org/2/library/stringio.html另外 ,您应该为 Python 3 使用 BytesIO。不过,它确实存在于 2.6 和 2.7 中。

于 2013-09-23T18:53:51.990 回答
2

这是一个使用示例(c)StringIO

from zipfile import ZipFile
try:
    import cStringIO as StringIO
except ImportError:
    import StringIO

in_memory = StringIO.StringIO()   
zf = ZipFile(in_memory, "a")  

zf.writestr("file.txt", "some text contents")

zf.close()

另见:

于 2013-09-23T18:56:45.703 回答