一尘不染

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

python

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

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

‘ZipFile’没有缓冲区接口。

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

这是我的代码:

@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')

阅读 200

收藏
2020-12-20

共1个答案

一尘不染

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

您可以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)

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

2020-12-20