django 下载文件的几种方法

转自:http://blog.sciencenet.cn/blog-47522-664541.html

django 下载文件的几种方法

from:http://oldj.net/article/django-big-file-response/

from:http://www.douban.com/group/topic/17856825/

from:http://hi.baidu.com/acmtiger/blog/item/e4e5b1874f529bb10df4d2b4.html

1、直接read/yeild返回给客户端

但 Django 中还没有实现对应的方法。一个解决办法是先将要传送的内容全生成在内存中,然后再一次性传入 HttpResponse,比如:


f =open(filename)
data = f.read()
f.close()
#以下设置项是为了下载任意类型文件
response = HttpResponse(data,mimetype='application/octet-stream') 
response['Content-Disposition'] = 'attachment; filename=%s' %filename
return response

  这样处理最简单粗暴,但也存在很大的问题,如果这个文件非常大,这样处理可能会占用大量的内存,甚至导致服务器崩溃。

  不过 Django 的开发者应该也考虑到了这种情况,官方文档中提到,可以给 HTTPResponse 传入一个迭代器,同时,StackOverflow上也有一个讨论这个问题的页面。根据这两个页面的内容,上面这个下载大文件的问题可以这样解决:

def bigFileView(request):
    # do something...
 
    def readFile(fn, buf_size=262144):
        f = open(fn, "rb")
        while True:
            c = f.read(buf_size)
            if c:
                yield c
            else:
                break
        f.close()
 
    file_name = "big_file.txt"
    response = HttpResponse(readFile(file_name))
 
    return response

 

 虽然这和其它语言中的 flush 不太一样,并且也并不是每次 yield 时客户端都会收到相应的内容(可能是因为服务器或客户端的缓冲),但这样的方法的确可以解决大文件或大内容下载的问题。经测试,使用这样的方法下载大文件时,服务器的内存占用几乎没有变化。

 

2、配置用户直接下载文件

经过urls.py的文件, 配置对应下载地址
e.g.,
...
(r'^download/(?P<path>.*)$', 'django.views.static.serve', {'document_root': your_download_path, 'show_indexes':True}),
...
http://xxxxx/download/a.txt

 

3、下载大文件和压缩zip文件

01.import os, tempfile, zipfile  
02.from django.http import HttpResponse  
03.from django.core.servers.basehttp import FileWrapper  
04. 
05. 
06.def send_file(request):  
07.    """                                                                          
08.    Send a file through Django without loading the whole file into               
09.    memory at once. The FileWrapper will turn the file object into an            
10.    iterator for chunks of 8KB.                                                  
11.    """ 
12.    filename = __file__ # Select your file here.                                  
13.    wrapper = FileWrapper(file(filename))  
14.    response = HttpResponse(wrapper, content_type='text/plain')  
15.    response['Content-Length'] = os.path.getsize(filename)  
16.    return response  
17. 
18. 
19.def send_zipfile(request):  
20.    """                                                                          
21.    Create a ZIP file on disk and transmit it in chunks of 8KB,                  
22.    without loading the whole file into memory. A similar approach can           
23.    be used for large dynamic PDF files.                                         
24.    """ 
25.    temp = tempfile.TemporaryFile()  
26.    archive = zipfile.ZipFile(temp, 'w', zipfile.ZIP_DEFLATED)  
27.    for index in range(10):  
28.        filename = __file__ # Select your files here.                             
29.        archive.write(filename, 'file%d.txt' % index)  
30.    archive.close()  
31.    wrapper = FileWrapper(temp)  
32.    response = HttpResponse(wrapper, content_type='application/zip')  
33.    response['Content-Disposition'] = 'attachment; filename=test.zip' 
34.    response['Content-Length'] = temp.tell()  
35.    temp.seek(0)  
36.    return response


  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值