Skip to main content
 首页 » 编程设计

python之内存 Zip 文件中的 Python 错误

2025年05月04日18虾米哥

我正在尝试用 Python 制作内存中的 zip 文件并将其上传到 Amazon S3。我已经阅读过关于此事的类似帖子,但无论我尝试什么,Windows 和 Linux (RHEL5) 都无法打开它(它已损坏)。这是我正在运行的代码:

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 documentation说:

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

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

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.x 中,您可能也想使用 BytesIO,只要您使用的是 2.6+。


此外,如果您使用 with 语句而不是尝试手动关闭,并且没有“不要尝试“在顶部声明变量”C 风格:

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,它不能直接用作上下文管理器,因此您必须将第一行替换为:

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