【问题标题】:flask make_response with large files带有大文件的烧瓶 make_response
【发布时间】:2014-08-10 16:03:56
【问题描述】:

因此,我对文件 I/O 和内存限制等方面非常满意,而且我很难让我的 Web 应用程序成功地将大文件下载服务到使用 flask 的 make_response 的 Web 浏览器。以下代码适用于较小的文件(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 的二进制数据粘贴到一个字符串中可能是一个很大的禁忌,但我不知道完成这些文件下载黑魔法的替代方法。如果有人可以让我在正确的轨道上使用 chunky[?] 或缓冲文件下载方法,或者只是将我指向一些中级资源以促进对这些东西的更深入理解,我将不胜感激。谢谢!

【问题讨论】:

  • 为什么要读取文件?您可以使用send_file() 函数让 Flask 为您提供文件。
  • @MartijnPieters 因为我不知道存在这样的功能:D 我只是重新设计了实现以使用它,现在我有另一个问题;它似乎记住了打开的给定类型的第一个文件,并将其用于该类型的所有后续文件。即,如果我有一堆 png 文件、一个 pdf 文件和一个 txt 文件,应用程序将成功下载第一个正确的 png,然后为每个其他 distinct png 文件提供相同的图像.在服务器端,我已经验证了 send_file 函数获得了正确的 png 路径,但它仍然行为不端。
  • 那么还有什么问题;这不是send_file() 本身可以产生的行为。

标签: python flask download


【解决方案1】:

请参阅Streaming Content 上的文档。基本上,您编写一个生成数据块的函数,然后将该生成器传递给响应,而不是一次传递整个数据。 Flask 和您的网络服务器完成剩下的工作。

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 的服务器,以便读取和发送数据高效。

【讨论】:

    【解决方案2】:

    您尝试的问题是,您首先将完整的内容读入“raw_bytes”,因此对于大文件,您很容易耗尽所有内存。

    有多种解决方案:

    流式传输内容

    正如 davidism answer 所解释的,您可以使用生成器传递 int 响应。这将逐个处理大文件,并且不需要太多内存。

    流不仅可以来自生成器,还可以来自文件,如shown in this anwer

    通过烧瓶提供静态文件

    如果您的文件是静态文件,请搜索如何配置 Flask 以提供静态文件。这些应以流式方式自动提供。

    通过apachenginx(或其他网络服务器)提供静态文件

    假设文件是​​静态的,您应该在生产环境中通过反向代理在您的 Flask 应用程序前为其提供服务。这不仅减轻了您的应用程序的负担,而且运行速度也更快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-11
      相关资源
      最近更新 更多