前言:
{BANNED}最佳近工作中需要使用django实现文件的下载功能。自己通过file.read方式实现后,在测试的过程中,发现当文件过大时,非常吃内存,为了优化 在网上找了一篇非常不错的文章解决了该问题!
-
django版本:1.8.2
-
python版本:2.7.10
实现思路详解:
1.使用了django的StreamingHttpResponse对象,以文件流的方式下载文件;
2.使用了迭代器(file_iterator()方法),将文件进行分割,避免消耗过多内存;
3.添加响应头:Content-Type 和 Content-Disposition,让文件流写入硬盘
代码:
-
# coding:utf-8
-
-
import json
-
import os
-
import traceback
-
import time
-
-
from django.http import HttpResponse
-
from django.http import StreamingHttpResponse
-
-
from rest_framework import viewsets
-
from rest_framework.decorators import list_route
-
-
-
class ExportFile(viewsets.GenericViewSet):
-
@staticmethod
-
def file_iterator(download_file, chunk_size=1024):
-
with open(download_file) as f:
-
while True:
-
c = f.read(chunk_size)
-
if c:
-
yield c
-
else:
-
break
-
-
@list_route(methods=["GET"])
-
def download(self, request):
-
"""下载"""
-
file_path = "需要下载的文件路径"
-
if not os.path.exists(file_path):
-
raise IOError("file not found!")
-
try:
-
file_name = os.path.basename(file_path)
-
file_name = "{file_name}_{timestamp}".format(file_name=file_name, timestamp=int(time.time()))
-
response = StreamingHttpResponse(self.file_iterator(file_path))
-
response["Content-Type"] = "application/octet-stream"
-
response["Content-Disposition"] = "attachment;filename={}".format(file_name)
-
return response
-
-
except Exception as e:
-
logger.error(e.message)
-
logger.error(traceback.format_exc())
-
return HttpResponse(json.dumps({"success": False, "error": u"下载文件失败"}), status=500,
-
content_type="text/json")
作者:white_study
链接:
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
阅读(403) | 评论(0) | 转发(0) |