• Python/Django 大文件下载问题


        最近使用Python/Django开发一个系统,暂且称之为A系统,卡在大文件下载上面,查询了django官方doc和stackoverflow上的很多资料,最终圆满解决此问题,如下为具体过程:


    一 A系统中的文件下载

        首先是在view中定义查询方法,在网站上点击查询按钮后,由后台生成相应的数据文件,并将文件名暂存cookie中;

        然后在在view中定义下载方法,采用FileWaper的方式,将文件打包为object,并返回response:

        参考链接:http://stackoverflow.com/questions/1156246/having-django-serve-downloadable-files

    1 response = HttpResponse(mimetype='application/force-download')
    2 response['Content-Disposition'] = 'attachment; filename=%s' % smart_str(file_name)
    3 response['X-Sendfile'] = smart_str(path_to_file)
    4 # It's usually a good idea to set the 'Content-Length' header too.
    5 # You can also set any other required headers: Cache-Control, etc.
    6 return response
    View Code

    二 遇到的问题与解决方法

        在template中配置好相应的内容,点击查询按钮,查出结果,然后点击下载按钮,问题来了,下载出来一个空文件;随即又多方查找,最后试验到另一个有效的下载方法:

        参考链接:https://djangosnippets.org/snippets/365/

     1 import os, tempfile, zipfile
     2 from django.http import HttpResponse
     3 from django.core.servers.basehttp import FileWrapper
     4 
     5 
     6 def send_file(request):
     7     """                                                                         
     8     Send a file through Django without loading the whole file into              
     9     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
    View Code

        但又出问题了,有的时候可以正常下载,有的时候下载出来也是一个空文件。经过多个参数的调试,终于发现规律,小文件下载没问题,大文件下载下来就是空的,这可真是奇怪。

        随后参考链接中的回复,将如下一行:

        wrapper = FileWrapper(file(filename))         修改为:

        wrapper = FileWrapper(open(filename, 'rb'))

        然后抱着试试看的态度,试了一下,没想到,it works!!!

    -------------------------------------------

    个性签名:Less is More!

    如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!

    从前写代码的时候,总想着测试,测试的时候,总想着用户体验;如今写代码的时候只写代码,测试的时候只测试,至于用户体验,那是后话 ^_^

  • 相关阅读:
    python RabbitMQ
    python IO多路复用版FTP
    python SelectPollEpoll异步IO与事件驱动
    python 同步与异步的性能区别及实例
    mysql学习笔记1---mysql ERROR 1045 (28000): 错误解决办法(续:深入分析)
    mysql学习笔记1---mysql ERROR 1045 (28000): 错误解决办法
    Ubuntu 安装HBase
    微博excel数据清洗(Java版)
    hadoop之mapreduce编程实例(系统日志初步清洗过滤处理)
    MapReduce编程实例6
  • 原文地址:https://www.cnblogs.com/chrisma/p/4169237.html
Copyright © 2020-2023  润新知