【问题标题】:Django 1.11 download file chunk by chunkDjango 1.11 逐块下载文件
【发布时间】:2017-09-21 07:59:12
【问题描述】:

就我而言,我将 Django 1.11 服务器用作代理。当您从浏览器单击“下载”时,它会向 django 代理发送请求,该代理从另一台服务器下载文件并处理它们,之后它们必须将它们“发送”到浏览器以允许用户下载它们。我的代理逐块下载和处理文件。 如何在它们准备好时将块发送到浏览器,以便用户最终下载单个文件?

实际上,我必须让你下载一个尚未准备好的文件,比如流。

def my_download(self, res)

   # some code
   file_handle = open(local_path, 'wb', self.chunk_size)

   for chunk in res.iter_content(self.chunk_size):
        i = i+1
        print("index: ", i, "/", chunks)
        if i > chunks-1:
            is_last = True

        # some code on the chunk

        # Here, instead of saving the chunk locally, I would like to allow it to download it directly.
        file_handle.write(chunk)
    file_handle.close()

    return True

提前谢谢你,问候。

【问题讨论】:

标签: python django download streaming


【解决方案1】:

此问题应标记为与此帖子重复:Serving large files ( with high loads ) in Django

请务必在 SO 中创建问题之前尝试找到答案!

答案基本上包含在 Django 的文档中:"Streaming Large CSV files" 示例,我们将把上述问题应用到该示例中:


您可以使用 Django 的 StreamingHttpResponse 和 Python 的 wsgiref.util.FileWrapper 有效地以块的形式提供大文件,而无需将其加载到内存中。

def my_download(request):
    file_path = 'path/to/file'
    chunk_size = DEFINE_A_CHUNK_SIZE_AS_INTEGER
    filename = os.path.basename(file_path)

    response = StreamingHttpResponse(
        FileWrapper(open(file_path, 'rb'), chunk_size),
        content_type="application/octet-stream"
    )
    response['Content-Length'] = os.path.getsize(file_path)    
    response['Content-Disposition'] = "attachment; filename=%s" % filename
    return response

现在,如果您想逐块对文件进行一些处理,您可以使用FileWrapper's 生成的迭代器:

将您的块处理代码放在一个必须返回块的函数中:

def chunk_processing(chunk):
    # Process your chunk here
    # Be careful to preserve chunk's initial size. 
    return processed_chunk

现在在StreamingHttpResponse中应用函数:

response = StreamingHttpResponse(
    (
        process_chunk(chunk) 
        for chunk in FileWrapper(open(file_path, 'rb'), chunk_size
    ),content_type="application/octet-stream"
)

【讨论】:

  • 在找到这个问题之前几分钟我一直在寻找那个答案(这就是我提出赏金的原因)。实际上“提供大文件”并不是我能想到的唯一用途,所以我没有考虑那样寻找它
  • @LuisSieira 我稍微编辑了我的答案,以包括对 OP 最初问题的部分答案。然而,这离重复的问题不远了……
  • 是的,应该像这样标记它,但它可以作为对前面问题答案的问题的重新表述。
  • 您将在 23 小时左右获得赏金
  • 是的,但只要赏金活动有效,我就不能。
猜你喜欢
  • 2014-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-18
  • 2013-05-03
  • 2018-11-15
  • 2018-04-09
  • 2012-11-18
相关资源
最近更新 更多