从web服务器向客户端传递二进制文件

5 投票
4 回答
7748 浏览
提问于 2025-04-16 08:56

通常,当我想把一个网页服务器上的文本文件传给客户端时,我会这样做:

import cgi

print "Content-Type: text/plain"
print "Content-Disposition: attachment; filename=TEST.txt"
print

filename = "C:\\TEST.TXT"
f = open(filename, 'r')
for line in f:
    print line

这样做对于ANSI格式的文件效果很好。但是,假设我有一个二进制文件 a.exe(这个文件在网页服务器的一个秘密路径下,用户不能直接访问那个目录)。我想用类似的方法来传输这个文件。我该怎么做呢?

  • 我应该使用什么样的内容类型?
  • 使用打印(print)似乎会导致客户端收到的内容出现损坏。正确的方法是什么?

我使用了以下代码:

#!c:/Python27/python.exe -u

import cgi

print "Content-Type: application/octet-stream"
print "Content-Disposition: attachment; filename=jstock.exe"
print

filename = "C:\\jstock.exe"
f = open(filename, 'rb')
for line in f:
    print line

但是,当我把下载的文件和原始文件进行比较时,发现每一行后面似乎多了一个空格(或者更多)。

alt text

4 个回答

1

.exe文件的内容类型通常是application/octet-stream,这表示它是一个二进制文件。
你可以用open(filename, 'rb')来打开这个文件,其中的b表示以二进制模式读取。

为了避免空格问题,你可以试试下面的方法:

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

或者更好的方法是,根据你的文件大小,使用Knio的方法:

fo = open(filename, "rb")
while True:
    buffer = fo.read(4096)
    if buffer:
        sys.stdout.write(buffer)
    else:
        break
fo.close()
2

在打开一个文件的时候,你可以用 open(filename, 'rb') 这个方式,其中的 'b' 表示你要以二进制的方式打开文件。对于一般的文件处理,你可以使用一些类似于“mime magic”的东西(我对在Python中怎么用不太了解,几年前我只在PHP中用过)。具体来说,.exe 文件的类型是 application/octet-stream

3

我同意上面提到的关于'rb'和内容类型头的看法。

另外:

for line in f:
    print line

在处理二进制文件时,如果遇到 \n\r\n 这些字节,可能会出现问题。这样做可能会更好:

import sys
while True:
    data = f.read(4096)
    sys.stdout.write(data)
    if not data:
        break

假设你是在Windows的CGI环境下运行这个程序,你需要用 -u 参数来启动Python进程,这样可以确保标准输出不是以文本模式运行。

撰写回答