我有一个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')
BytesIO()需要传递 字节数据 ,但ZipFile()对象不是字节数据;您实际上在 硬盘上 创建了一个文件。
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)电话是需要“倒带”文件对象回到开始的读写位置。
with
memory_file.seek(0)