在String

时间:2016-03-02 20:25:04

标签: python zipfile shutil stringio

我使用StringIOzipfile创建了一个内存中的zip文件:

inMemoryZip = StringIO()
outfile = zipfile.ZipFile(inMemoryZip, 'w', compression=zipfile.ZIP_DEFLATED)
//outfile.write(stuff)
inMemoryZip.seek(0)
return inMemoryZip

此数据上传到服务器/数据库。在某些时候,它被检索,我需要将其作为zip文件写入磁盘。我不知道该怎么做。我尝试了以下方法:

with open('pathToNewZip.zip', 'w') as archive:
  archive.write(inMemoryZip.getvalue())

这会创建zip文件存档,但是当我双击它时,我看不到它的内容,它基本上会创建一个自身的副本(另一个相同的.zip文件, ,但扩展名是。 zip.cpgz )旁边的原始

我也尝试过:

with open('pathToNewZip.zip', 'w') as archive:
      shutil.copyfileobj(inMemoryZip, archive)

但与上述结果相同。

我猜部分问题是我不知道如何解析这些数据。 inMemoryZipStringIO的实例)可能包含多个文件。

每个文件都写成新行吗?

.getvalue()返回什么? StringIO实例中所有文件的数据?

如何确定我之前压缩的文件的名称,以便可以使用相同的名称重新创建它们?

有这样的:How can I pass a Python StringIO() object to a ZipFile(), or is it not supported?但看起来如果一次只写入1个文件就行了。我的StringIO实例可以包含1个文件或10个文件。

1 个答案:

答案 0 :(得分:2)

您需要按照@Kupiakos的建议打开最终文件“wb”,否则最终会导致存档损坏。您的另一个问题是在使用StringIO缓冲区之前需要关闭zip文件。 close将文件目录写入zipfile。如果没有这个,一个解压缩器可能会做出这样的假设,例如这只是多部件拉链中的一个并做奇怪的事情。名义上,只需添加outfile.close()或将其放入上下文管理器

即可
inMemoryZip = StringIO()
with zipfile.ZipFile(inMemoryZip, 'w', compression=zipfile.ZIP_DEFLATED) as output:
    //outfile.write(stuff)
inMemoryZip.seek(0)
return inMemoryZip

然后再

with open('pathToNewZip.zip', 'wb') as archive:
  archive.write(inMemoryZip.getvalue())