代码之家  ›  专栏  ›  技术社区  ›  Scott

用python提供文件下载服务

  •  1
  • Scott  · 技术社区  · 15 年前

    嘿,帮派,我正试图把一个遗留的PHP脚本转换成python,但运气不好。

    脚本的目的是在隐藏文件来源的同时提供一个文件。下面是在PHP中工作的内容:

    <?php
    $filepath = "foo.mp3";
    
    $filesize = filesize($filepath);
    
    header("Pragma: no-cache");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    
    // force download dialog
    //header("Content-Type: application/force-download");
    header("Content-Type: application/octet-stream");
    header("Content-Type: application/download");
    
    header('Content-Disposition: attachment;filename="'.$filepath.'"');
    
    header("Content-Transfer-Encoding: binary");
    
    #header('Content-Type: audio/mpeg3');
    header('Content-Length: '.$filesize);
    
    @readfile($filepath);
    exit(0);
    ?>
    

    当我在python中做类似的工作时,我得到了一个零字节的下载。以下是我的尝试:

    #!/usr/bin/env python
    # encoding: utf-8
    
    import sys
    import os
    import cgitb; cgitb.enable()
    
    filepath = "foo.mp3" 
    filesize = os.path.getsize(filepath)
    
    print "Prama: no-cache"
    print "Expires: 0"
    print "Cache-Control: must-revalidate, post-check=0, pre-check=0"
    
    print "Content-Type: application/octet-stream"
    print "Content-Type: application/download"
    
    print 'Content-Disposition: attachment;filename="'+filepath+'"'
    
    print "Content-Transfer-Encoding: binary"
    
    print 'Content-Length: '+str(filesize)
    
    print  #required blank line
    
    open(filepath,"rb").read()
    

    有人能帮我吗?

    3 回复  |  直到 15 年前
        1
  •  5
  •   Dirk    15 年前

    好吧,也许只是我错过了什么,但是…实际上,您没有将文件的内容写入stdout。你只是把它读到内存中,所以它永远不会出现在TCP连接的另一端…

    尝试:

    sys.stdout.write(open(filepath,"rb").read())
    sys.stdout.flush()
    

    根据文件大小的不同,最好是分块读取文件,如:

    chunk_size = 4096
    handle = open(filepath, "rb")
    
    while True:
        buffer = handle.read(chunk_size)
        if buffer:
            sys.stdout.write(buffer)
        else:
            break
    

    另一件需要注意的事情是:将二进制数据写入stdout可能会由于编码问题而导致python阻塞。这取决于您使用的Python版本。

        2
  •  1
  •   Greg    15 年前

    我不知道这是否是唯一的问题,但是python print语句用“\n”终止行,而http头需要用“\r\n”终止。

        3
  •  -1
  •   Ólafur Waage    15 年前

    你应该退房 urllib 设置和使用标题。 Here's a small example 就是这样。