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