一.使用HttpResponse
#直接传入内容
content= b'123456789sdfkjhglbdsjhfjgfb'
response = HttpResponse(content,content_type='application/octet-stream') #文件流类型
response['Content-Disposition'] = 'attachment; filename={}'.format('2222.txt') #表示带有文件附件,指定了文件名;浏览器会自动下载
return response
f = open('/data/text.zip','rb')
response = HttpResponse(f,content_type='application/octet-stream') #文件流类型
response['Content-Disposition'] = 'attachment; filename={}'.format('2222.txt') #表示带有文件附件,指定了文件名;浏览器会自动下载
return response
弊端:
从以下源码可知,httpresponse对象初始化时会将文件内容载入内存:当文件过大时会大量占用服务器内存
文件下载建议使用下面对象
二.使用SteamingHttpResonse
流类型
import os
from django.http import HttpResponse, Http404, StreamingHttpResponse
def stream_http_download(request, file_path):
try:
response = StreamingHttpResponse(open(file_path, 'rb'))
response['content_type'] = "application/octet-stream"
response['Content-Disposition'] = 'attachment; filename=' + os.path.basename(file_path)
return response
except Exception:
raise Http404
源码:
将传入对象转为迭代器,而不是一次性加载到内存
def _set_streaming_content(self, value):
# Ensure we can never iterate on "value" more than once.
self._iterator = iter(value)
if hasattr(value, 'close'):
self._resource_closers.append(value.close)
三.使用FileResponse
为文件传输优化的流类型
import os
from django.http import HttpResponse, Http404, FileResponse
def file_response_download1(request, file_path):
try:
response = FileResponse(open(file_path, 'rb'))
response['content_type'] = "application/octet-stream"
response['Content-Disposition'] = 'attachment; filename=' + os.path.basename(file_path)
return response
except Exception:
raise Http404
源码:
迭代器中每次一固定大小读取文件,默认值:block_size = 4096
def _set_streaming_content(self, value):
if not hasattr(value, 'read'):
self.file_to_stream = None
return super()._set_streaming_content(value)
self.file_to_stream = filelike = value
if hasattr(filelike, 'close'):
self._resource_closers.append(filelike.close)
value = iter(lambda: filelike.read(self.block_size), b'')
self.set_headers(filelike)
super()._set_streaming_content(value)
版权声明:本文为qq_37674086原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。