【问题标题】:In Memory Zip File Python Error内存 Zip 文件 Python 错误
【发布时间】:2013-06-22 23:15:04
【问题描述】:

我正在尝试用 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()

【问题讨论】:

  • 首先,您是否尝试过将.zip文件保存在本地并打开它,看看问题是否与S3有关?

标签: python amazon-s3 zip zipfile stringio


【解决方案1】:

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

正如the documentation 所说:

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

最重要的是,虽然它有时有效,但实际上在封闭的StringIO 上调用getvalue() 是不合法的。同样,来自the docs

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

最后,如果您使用的是 Python 3.x,您可能希望使用 BytesIO 而不是 StringIO。事实上,即使在 2.x 中,您也可能希望使用 BytesIO,只要您使用的是 2.6+。


此外,如果您使用 with 语句而不是手动尝试 close 并且没有尝试“在顶部声明变量”,您的代码将更具可读性,并且更难出错" 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:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-11
    • 2013-08-29
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多