通常,当我想将Web服务器文本文件传输到客户端时,这就是我所做的
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
(此文件位于Web服务器的秘密路径中,用户不能直接访问该目录路径)。我希望使用类似的方法来转移。我怎么能这样做?
我使用以下代码。
#!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
但是,当我将下载的文件与原始文件进行比较时,似乎每一行后都有一个额外的空格(或更多)。
答案 0 :(得分:3)
同意以上关于'rb'和Content-Type标题的海报。
此外:
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
假设这是在CGI环境中的Windows上运行,您将需要使用-u
参数启动python进程,这将确保stdout不在文本模式下
答案 1 :(得分: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 :(得分:1)
打开文件时,可以使用open(filename, 'rb')
- 'b'标志将其标记为二进制。对于一般处理程序,你可以使用某种形式的mime魔法(我不熟悉从Python中使用它,我几年前才从PHP中使用它)。对于特定情况,.exe
为application/octet-stream
。
答案 3 :(得分:0)
对于使用Windows Server 2008或2012和Python 3的任何人来说,这里有更新......
经过数小时的实验,我发现以下内容可靠地运作:
import io
with io.open(sys.stdout.fileno(),"wb") as fout:
with open(filename,"rb") as fin:
while True:
data = fin.read(4096)
fout.write(data)
if not data:
break