Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2268381
  • 博文数量: 293
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2170
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-31 14:30
个人简介

自己慢慢积累。

文章分类

全部博文(293)

分类: Python/Ruby

2022-12-19 20:29:51

前言:

{BANNED}最佳近工作中需要使用django实现文件的下载功能。自己通过file.read方式实现后,在测试的过程中,发现当文件过大时,非常吃内存,为了优化 在网上找了一篇非常不错的文章解决了该问题!

  • django版本:1.8.2
  • python版本:2.7.10
实现思路详解:

1.使用了django的StreamingHttpResponse对象,以文件流的方式下载文件;
2.使用了迭代器(file_iterator()方法),将文件进行分割,避免消耗过多内存;
3.添加响应头:Content-Type 和 Content-Disposition,让文件流写入硬盘

代码:

  1. # coding:utf-8

  2. import json
  3. import os
  4. import traceback
  5. import time

  6. from django.http import HttpResponse
  7. from django.http import StreamingHttpResponse

  8. from rest_framework import viewsets
  9. from rest_framework.decorators import list_route


  10. class ExportFile(viewsets.GenericViewSet):
  11.     @staticmethod
  12.     def file_iterator(download_file, chunk_size=1024):
  13.         with open(download_file) as f:
  14.             while True:
  15.                 c = f.read(chunk_size)
  16.                 if c:
  17.                     yield c
  18.                 else:
  19.                     break

  20.     @list_route(methods=["GET"])
  21.     def download(self, request):
  22.         """下载"""
  23.         file_path = "需要下载的文件路径"
  24.         if not os.path.exists(file_path):
  25.             raise IOError("file not found!")
  26.         try:
  27.             file_name = os.path.basename(file_path)
  28.             file_name = "{file_name}_{timestamp}".format(file_name=file_name, timestamp=int(time.time()))
  29.             response = StreamingHttpResponse(self.file_iterator(file_path))
  30.             response["Content-Type"] = "application/octet-stream"
  31.             response["Content-Disposition"] = "attachment;filename={}".format(file_name)
  32.             return response

  33.         except Exception as e:
  34.             logger.error(e.message)
  35.             logger.error(traceback.format_exc())
  36.             return HttpResponse(json.dumps({"success": False, "error": u"下载文件失败"}), status=500,
  37.                                 content_type="text/json")





作者:white_study
链接:
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
阅读(403) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~