内存中的Zip文件Python错误 [英] In Memory Zip File Python Error
问题描述
我正在尝试使用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 theStringIO
object’sclose()
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屋!