【问题标题】:Python generated zipfile is corruptedPython 生成的 zipfile 已损坏
【发布时间】:2018-10-01 02:11:37
【问题描述】:

我有一个像下面这样的 Flask 视图,它生成几个 CSV 文件并将它们放在一个 zip 存档中以发送给用户。

@route('/download/<int:some_value>')
def download(self, some_value):
    """Return a ZIP archive with several CSVs in"""
    # ensure the thing exists
    at = (MyModel.SomeModel
                 .query
                 .filter((MyModel.SomeModel
                                 .some_primary_key) == some_value)
                 .first_or_404())
    # what queries do we need to run?
    queries = cascade_export(at)
    # prepare a zip
    out = BytesIO()
    with zipfile.ZipFile(out, 'w') as zf:
        # run each query
        for tn, q in queries.items():
            # make the query
            conn = db.engine.connect()
            r = conn.execute(q.query, **q.params)
            conn.close()
            # map the col names
            cols = [c.name for c in r.cursor.description]
            col_map = {
                c.name: c.key
                for c in q.model.__table__.columns
            }
            col_order = [col_map[c] for c in cols]
            # put it into a csv in memory
            f = StringIO()
            writer = csv.DictWriter(f, fieldnames=col_order)
            for row in r:
                writer.writerow({
                    k: v
                    for k, v in zip(col_order, row)
                })
            # write it into the zip
            f.seek(0)
            zf.writestr('{0}.csv'.format(q.model.__name__), f.read())

    out.seek(0)

    fn = 'export-{0}-{1}.zip'.format(
        at.some_name,
        datetime.datetime.now().strftime('%d-%m-%Y-%H-%M-%S')
    )
    return send_file(out,
                     attachment_filename=fn,
                     as_attachment=True,
                     cache_timeout=0)

在我的测试中,r 是一个响应对象,以下都通过:

assert r.status_code == 200
zf = zipfile.ZipFile(io.BytesIO(r.data))
assert zf.testzip() is None

但是,当我尝试在 ubuntu 中打开文件时,我得到以下信息:

Archive:  ../downloads/export-Something-20-04-2018-11-59-04.zip
warning [../downloads/export-Something-20-04-2018-11-59-04.zip]:  300 extra bytes at beginning or within zipfile
  (attempting to process anyway)
error [../downloads/export-Something-20-04-2018-11-59-04.zip]:  start of central directory not found;
  zipfile corrupt.
  (please check that you have transferred or created the zipfile in the
  appropriate BINARY mode and that you have compiled UnZip properly)

对此非常感谢的任何想法/帮助。

【问题讨论】:

  • 尝试以二进制模式写入:with zipfile.ZipFile(out, 'wb') as zf:
  • 这给了我RuntimeError: ZipFile requires mode 'r', 'w', 'x', or 'a'
  • 你在客户端使用requests吗?
  • @jdehesa - 我正在使用烧瓶测试客户端 (with app.test_client() as client:),python 似乎可以正常打开该文件,但是当我在浏览器中运行它并下载文件时,它已损坏。
  • 如果我在浏览器中下载文件,然后尝试打开它,我会得到zipfile.BadZipFile: Bad magic number for central directory

标签: python python-3.x flask


【解决方案1】:

问题不在于 Python,而在于下载文件的方式。很明显,如果 python 测试通过,则 zip 文件可能是合法的!如果您不太可能遇到同样的错误,请确保您的 HTTP 库期待正确类型的响应,对于axios,这意味着设置responseType to 'bytearray'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-29
    • 1970-01-01
    • 2016-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多