所以我真正的绿色文件I / O和内存限制等等,而且我很难让我的Web应用程序成功地将大型文件下载到带有烧瓶的Web浏览器中#&# 39; s make_response
。以下代码适用于较小的文件(< ~1GB),但当我进入较大的文件时,我会遇到MemoryError
异常:
raw_bytes = ""
with open(file_path, 'rb') as r:
for line in r:
raw_bytes = raw_bytes + line
response = make_response(raw_bytes)
response.headers['Content-Type'] = "application/octet-stream"
response.headers['Content-Disposition'] = "inline; filename=" + file_name
return response
我假设将超过2 GB的二进制数据粘贴到一个字符串中可能是一个很大的禁忌,但我不知道如何替代完成这些文件下载黑色魔法。如果有人可以通过粗略的[?]或缓冲的文件下载方法让我走上正轨,或者只是指向一些中级资源以便更深入地了解这些内容,我将非常感激。谢谢!
答案 0 :(得分:19)
请参阅Streaming Content上的文档。基本上,您编写了一个产生数据块的函数,并将该生成器传递给响应,而不是将整个事件传递给响应。 Flask和您的Web服务器完成剩下的工作。
from flask import stream_with_context, Response
@app.route('/stream_data')
def stream_data():
def generate():
# create and return your data in small parts here
for i in xrange(10000):
yield str(i)
return Response(stream_with_context(generate()))
如果文件是静态的,您可以改为利用send_from_directory()
。文档建议您使用nginx或其他支持X-SendFile的服务器,以便读取和发送数据是有效的。
答案 1 :(得分:2)
您尝试的问题是,您首先将完整内容读入" raw_bytes",因此对于大文件,您很容易耗尽所有内存。
有多种方法可以解决这个问题:
正如davidism回答所解释的,你可以使用一个传递给int的生成器。这可以逐个提供大文件,并且不需要太多内存。
流式传输不仅可以来自生成器,还可以来自文件,如shown in this anwer
如果您的文件是静态的,请搜索如何配置Flask以提供静态文件。这些应以流媒体方式自动提供。
apache
或nginx
(或其他网络服务器)上提供静态文件假设该文件是静态的,您将在生产中通过Flask应用程序前面的反向代理服务。这不仅可以卸载您的应用程序,而且还可以更快地运行。