使用python提供文件下载

时间:2009-09-05 21:38:19

标签: php python binary

嘿帮派,我正在尝试将遗留的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中执行equivilent时,我得到一个零字节的下载。这是我正在尝试的:

#!/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 个答案:

答案 0 :(得分:5)

好吧,也许只是我遗漏了一些东西,但是......你实际上并没有把文件的内容写到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版本。

答案 1 :(得分:1)

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

答案 2 :(得分:-1)

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