【问题标题】:Serving file download with python使用 python 服务文件下载
【发布时间】:2010-11-25 22:34:00
【问题描述】:

嘿,伙计,我正在尝试将旧的 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()

谁能帮帮我?

【问题讨论】:

    标签: php python binary


    【解决方案1】:

    好吧,也许只是我遗漏了一些东西,但是...您实际上并没有将文件的内容写入标准输出。您只是将它读入内存,因此它永远不会出现在 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
    

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

    【讨论】:

    • 哇,我以前从来没有在这个论坛上发过帖子。你们真是不可思议!
    • Scott,如果某个答案解决了您的问题,请记住接受它(使用数字下方的复选标记图标为答案投票):这是基本的 SO 行为!
    【解决方案2】:

    我不知道这是否是唯一的问题,但 python 打印语句以“\n”终止行,而 HTTP 标头需要以“\r\n”终止

    【讨论】:

      【解决方案3】:

      您应该查看urllib 以设置和使用标头。 Here's a small example 就是这样做的。

      【讨论】:

      • 我一直不明白如何在 ajax 情况下使用这个模块。与示例中一样,所有标头和 url 共同构成一个请求,但我正在响应,而不是发出请求。它是如何工作的?
      • urllib 和 urllib2 库确实是用于操作 ulr(发出 http 请求)而不是响应它们 - 所以这个答案没有帮助。
      猜你喜欢
      • 2019-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多