是否可以在Python 2.6中将stdin读取为二进制数据?如果是这样,怎么样?
我在Python 3.1 documentation中看到这很简单,但在2.6中执行此操作的设施似乎并不存在。
如果3.1中描述的方法不可用,有没有办法关闭stdin并以二进制模式重新打开?
更新
为了清楚起见,我在MS-DOS shell中使用'type'来将二进制文件的内容传递给我的python代码。据我所知,这应该相当于Unix'cat'命令。但是当我测试它时,我总是比预期的文件大小少一个字节。
更新#2
首先,感谢所有答案。我正在慢慢努力寻找一个真实可用的解决方案。最后,我仍然在尝试构建一个自包含的JAR文件,该文件执行我的Python代码,自动传递所有未触及的命令行参数。
我要使用Java / JAR / Jython路由的原因是因为我的一个主要外部库仅作为Java JAR提供。但不幸的是,我开始以Python开展工作。不久前将代码转换为Java可能更容易,但由于这些东西都应该是兼容的,我想我会尝试通过它来证明它可以完成。
如果有人想知道,这也与我几天前提出的问题有关。
Packaging and deploying a Jython program from Eclipse
有些问题已在question中得到解答。
因此,我会尝试更新我原来的问题,并附上一些关于我到目前为止已经弄清楚的内容。
答案 0 :(得分:21)
从文档(参见here):
标准流处于文本模式 默认情况下。写或读二进制 数据到这些,使用底层 二进制缓冲区例如,要写 字节到标准输出,使用
sys.stdout.buffer.write(b'abc')
。
但是,正如在接受的答案中,使用-u
调用python是另一种选择,它强制stdin,stdout和stderr完全无缓冲。有关详细信息,请参阅python(1)联机帮助页。
有关文本缓冲的更多信息,请参阅documentation on io
,并使用sys.stdin.detach()
禁用Python中的缓冲。
答案 1 :(得分:13)
以下是Linux / Windows Python 2/3兼容代码的最终版本,用于从stdin读取数据而不会损坏:
import sys
PY3K = sys.version_info >= (3, 0)
if PY3K:
source = sys.stdin.buffer
else:
# Python 2 on Windows opens sys.stdin in text mode, and
# binary data that read from it becomes corrupted on \r\n
if sys.platform == "win32":
# set sys.stdin to binary mode
import os, msvcrt
msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
source = sys.stdin
b = source.read()
答案 2 :(得分:12)
使用-u
command line switch强制Python 2将stdin,stdout和stderr视为二进制无缓冲流。
C:> type mydoc.txt | python.exe -u myscript.py
答案 3 :(得分:9)
如果你还需要这个...... 我用这个简单的测试来读取
之间包含0x1A字符的二进制文件import os, sys, msvcrt
msvcrt.setmode (sys.stdin.fileno(), os.O_BINARY)
s = sys.stdin.read()
print len (s)
我的测试文件数据是:
0x23, 0x1A, 0x45
如果不将stdin设置为二进制模式,则只要将0x1A视为EOF,此测试就会打印1。 当然它只适用于Windows,因为它取决于msvcrt模块。
答案 4 :(得分:0)
您可以使用以下方法执行无缓冲读取:
os.read(0, bytes_to_read)
其中0是stdin的文件描述符
答案 5 :(得分:-2)
import sys
data = sys.stdin.read(10) # Read 10 bytes from stdin
如果您需要解释二进制数据,请使用struct
模块。