就我而言,我将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
提前谢谢你,问候。
答案 0 :(得分:5)
此问题应标记为此帖的重复: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
现在,如果你想对chunk-by-chunk文件应用一些处理,你可以利用FileWrapper
's生成的迭代器:
将块处理代码放在必须返回块的函数中:
def chunk_processing(chunk):
# Process your chunk here
# Be careful to preserve chunk's initial size.
return processed_chunk
中应用该功能
response = StreamingHttpResponse(
(
process_chunk(chunk)
for chunk in FileWrapper(open(file_path, 'rb'), chunk_size
),content_type="application/octet-stream"
)