如何在python Flask框架中发送zip文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27337013/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 01:41:03  来源:igfitidea点击:

How to send zip files in the python Flask framework?

pythonhttpflaskzipfile

提问by idungotnosn

I have a flask server that grabs binary data for several different files from a database and puts them into a python 'zipfile' object. I want to send the generated zip file with my code using flask's "send_file" method.

我有一个 Flask 服务器,它从数据库中获取几个不同文件的二进制数据,并将它们放入 python 'zipfile' 对象中。我想使用flask的“send_file”方法将生成的zip文件和我的代码一起发送。

I was originally able to send non-zip files successfully by using the BytesIO(bin) as the first argument to send_file, but for some reason I can't do the same thing with my generated zip file. It gives the error:

我最初能够通过使用 BytesIO(bin) 作为 send_file 的第一个参数来成功发送非 zip 文件,但由于某种原因,我无法对生成的 zip 文件执行相同的操作。它给出了错误:

'ZipFile' does not have the buffer interface.

'ZipFile' 没有缓冲区接口。

How do I send this zip file object to the user with Flask?

如何使用 Flask 将此 zip 文件对象发送给用户?

This is my code:

这是我的代码:

@app.route("/getcaps",methods=['GET','POST'])
def downloadFiles():
    if request.method == 'POST':
        mongo = MongoDAO('localhost',27017)
        identifier = request.form['CapsuleName']
        password = request.form['CapsulePassword']
        result = mongo.getCapsuleByIdentifier(identifier,password)
        zf = zipfile.ZipFile('capsule.zip','w')
        files = result['files']
        for individualFile in files:
            data = zipfile.ZipInfo(individualFile['fileName'])
            data.date_time = time.localtime(time.time())[:6]
            data.compress_type = zipfile.ZIP_DEFLATED
            zf.writestr(data,individualFile['fileData'])
        return send_file(BytesIO(zf), attachment_filename='capsule.zip', as_attachment=True)
    return render_template('download.html')

采纳答案by Martijn Pieters

BytesIO()needs to be passed bytes data, but a ZipFile()object is not bytes-data; you actually created a file on your harddisk.

BytesIO()需要传递字节数据,但ZipFile()对象不是字节数据;您实际上在硬盘上创建了一个文件。

You can create a ZipFile()in memory by using BytesIO()as the base:

您可以ZipFile()使用BytesIO()作为基础在内存中创建一个:

memory_file = BytesIO()
with zipfile.ZipFile(memory_file, 'w') as zf:
    files = result['files']
    for individualFile in files:
        data = zipfile.ZipInfo(individualFile['fileName'])
        data.date_time = time.localtime(time.time())[:6]
        data.compress_type = zipfile.ZIP_DEFLATED
        zf.writestr(data, individualFile['fileData'])
memory_file.seek(0)
return send_file(memory_file, attachment_filename='capsule.zip', as_attachment=True)

The withstatement ensures that the ZipFile()object is properly closed when you are done adding entries, causing it to write the required trailer to the in-memory file object. The memory_file.seek(0)call is needed to 'rewind' the read-write position of the file object back to the start.

with语句可确保ZipFile()在您完成添加条目后正确关闭对象,从而使其将所需的预告片写入内存文件对象。该memory_file.seek(0)电话是需要“倒带”文件对象回到开始的读写位置。