Django 1.11逐块下载文件

use*_*543 0 python django streaming download

就我而言,我让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
Run Code Online (Sandbox Code Playgroud)

预先谢谢您的问候。

Joh*_*fis 6

这个问题应该标记为这篇文章的重复:在Django中提供大文件(高负载)

在用SO创建问题之前,请务必尝试找到答案。

本质上,答案包含在Django的文档中:“流式处理大型CSV文件”示例,我们将上述问题应用于该示例:


您可以使用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
Run Code Online (Sandbox Code Playgroud)

现在,如果你想要一些处理应用于块逐块,你可以利用文件FileWrapper生成迭代器:

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

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

现在在下面应用函数StreamingHttpResponse

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