2017-04-24 54 views
0

在我的情况下,我有Django 1.11服务器充当代理。当您从浏览器中点击“下载”时,它会向django代理发送请求,从其他服务器下载文件并对其进行处理,然后将其发送到浏览器以允许用户下载。我的代理通过块下载并处理文件块。 如何在浏览器准备就绪时向浏览器发送块,以便用户最终下载单个文件?Django 1.11通过块下载文件块

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

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 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

我终于找到了答案在这里:https://stackoverflow.com/questions/38514919/django-stream-request-from-external-site-as-received 这个问题实际上是一个dupplicate –

+0

是的,这里https://stackoverflow.com/questions/48949022/django-filewrapper-memory-error-serving-big-files-how-to-stream/48949959#48949959 – trinchet

+0

而在这里:https:// stackoverflow。 com/questions/8600843/serving-large-files-with-high-loads-in-django?answertab = votes#tab-top –

回答

2

这个问题应该被标记为这篇文章的重复:Serving large files (with high loads) in Django

应尽量您在SO创建一个问题之前找到答案,请!

本质的答案被包含在Django的文档:"Streaming Large CSV files"例如我们会申请对上述问题成例如:


您可以使用Django的StreamingHttpResponse和Python的wsgiref.util.FileWrapper服务于块大文件effectivelly并且不需要将其加载到内存中。

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产生的迭代器:

放置在一个函数的块处理代码MUST返回大块:

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" 
) 
+0

我正在寻找回答几分钟后才发现这个问题(这就是为什么我提出了奖励)。其实“服务大文件”并不是我能想到的唯一用途,所以我没有考虑像那样寻找它 –

+0

@LuisSieira我编辑了我的答案,包含了OP最初问题的一部分答案。尽管如此,这不是一个重复的问题... –

+0

是的,它应该像这样标记,但作为解决前面问题答案的问题的重新表述很有用。 –