从stdin读取二进制数据

时间:2010-05-17 16:34:21

标签: python python-2.x

是否可以在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中得到解答。

因此,我会尝试更新我原来的问题,并附上一些关于我到目前为止已经弄清楚的内容。

6 个答案:

答案 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模块。