内存中的Zip文件Python错误 [英] In Memory Zip File Python Error

查看:157
本文介绍了内存中的Zip文件Python错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Python创建内存中的zip文件并将其上传到Amazon S3.我已经读过类似的文章,但是无论我如何尝试,Windows和Linux(RHEL5)都无法打开它(它已损坏).这是我正在运行的代码:

I'm trying to make an in-memory zip file in Python and upload it to Amazon S3. I've read the similar posts on the matter, but no matter what I try, Windows and Linux (RHEL5) cannot open it (it's corrupt). Here's the code I'm running:

f_redirects = StringIO()
f_links = StringIO()
f_metadata = StringIO()

# Write to the "files"

zip_file = StringIO()
zip = zipfile.ZipFile(zip_file, 'a', zipfile.ZIP_DEFLATED, False)
zip.writestr('redirects.csv', f_redirects.getvalue())
zip.writestr('links.csv', f_bad_links.getvalue())
zip.writestr('metadata.csv', f_metadata.getvalue())

f_redirects.close()
f_links.close()
f_metadata.close()

k = Key(BUCKET)
k.key = '%s.zip' % base_name
k.set_metadata('Content-Type', 'application/zip')
k.set_contents_from_string(zip_file.getvalue())
zip.close()
zip_file.close()

推荐答案

问题是您要在调用close之前尝试使用ZipFile的内容.

The problem is that you're trying to use the contents of the ZipFile before you call close on it.

文档所述:

您必须致电close()…否则基本记录将不会被写入.

You must call close() … or essential records will not be written.

最重要的是,尽管有时它可以工作,但是在封闭的StringIO上调用getvalue()实际上是不合法的.同样,来自文档:

On top of that, although it sometimes works, it's actually not legal to call getvalue() on a closed StringIO. Again, from the docs:

在调用StringIO对象的close()方法之前的任何时候,返回一个包含缓冲区全部内容的str.

Return a str containing the entire contents of the buffer at any time before the StringIO object’s close() method is called.

最后,如果您使用的是Python 3.x,则可能要使用BytesIO而不是StringIO.实际上,只要您使用的是2.6+,就可能甚至要在2.x中使用BytesIO.

Finally, if you're using Python 3.x, you probably want to use BytesIO rather than StringIO. In fact, you might want to use BytesIO even in 2.x, as long as you're using 2.6+.

此外,如果您使用with语句而不是尝试手动close进行操作,并且不尝试在顶部声明变量",那么您的代码将更具可读性,并且更容易出错. "C风格:

Also, your code would be a lot more readable, and harder to get wrong, if you used with statements instead of trying to close things manually, and didn't try to "declare your variables at the top" C-style:

with BytesIO() as zip_file:
    with zipfile.ZipFile(zip_file, 'a', zipfile.ZIP_DEFLATED, False) as zip:
        zip.writestr('redirects.csv', f_redirects.getvalue())
        zip.writestr('links.csv', f_bad_links.getvalue())
        zip.writestr('metadata.csv', f_metadata.getvalue())
    zip_contents = zip_file.getvalue()

k = Key(BUCKET)
k.key = '%s.zip' % base_name
k.set_metadata('Content-Type', 'application/zip')
k.set_contents_from_string(zip_contents)

如果您使用的是Python 2.x,并且希望继续使用StringIO,则它不能直接用作上下文管理器,因此您必须将第一行替换为:

If you're using Python 2.x, and want to stay with StringIO, it isn't directly usable as a context manager, so you'll have to replace the first line with:

with contextlib.closing(StringIO()) as zip_file:

这篇关于内存中的Zip文件Python错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆