使用IronPython向标准输出写入二进制数据
我有两个Python脚本,正在Windows上用IronPython 2.6和.NET 2.0运行。一个脚本输出二进制数据,另一个脚本处理这些数据。我希望能通过管道把第一个脚本的数据流传输到第二个脚本。但是我遇到的问题是,当我从Windows命令行运行时,sys.stdout
使用的是CP437字符编码,并且是文本模式,而不是二进制模式(也就是用'w'
而不是'wb'
)。这导致一些大于127的字节被写成了错误的字符(也就是说,不同的字节值在输出中产生相同的字符,因此读取它们的脚本无法区分)。
举个例子,这个脚本打印了同一个字符(下划线)两次:
import sys
sys.stdout.write(chr(95))
sys.stdout.write(chr(222))
所以当我尝试读取数据时,得到的结果和我最初写的内容不一样。
我写了这个脚本来检查问题是出在用'w'
模式写入,还是编码的问题:
import sys
str = chr(222)
# try writing chr(222) in ASCII in both write modes
# ASCII is the default encoding
open('ascii_w', 'w').write(str)
open('ascii_wb', 'wb').write(str)
# set encoding to CP437 and try writing chr(222) in both modes
reload(sys)
sys.setdefaultencoding("cp437")
open('cp437_w', 'w').write(str)
open('cp437_wb', 'wb').write(str)
运行后,文件cp437_w
包含字符95,而其他三个文件各自包含字符222。因此,我认为问题是由于CP437编码和用'w'
模式写入的组合造成的。在这种情况下,如果我能强制stdout
使用二进制模式,那就能解决这个问题(我假设让它使用ASCII编码是不可能的,因为cmd.exe使用的是CP437)。但我在这方面遇到了瓶颈,找不到任何方法来实现。
我找到了一些可能的解决方案,但都没有成功:
- 运行
ipy -u
似乎没有任何效果(我还测试过它是否会导致Unix风格的换行符被打印;结果没有,所以我怀疑-u
根本不适用于IronPython) - 我不能使用这个解决方案,因为
msvcrt
在IronPython中不支持 - 在Python 3.x中,可以通过
sys.stdout.buffer
访问无缓冲的stdout
;但在2.6中没有这个功能 os.fdopen(sys.stdout.fileno(), 'wb', 0)
只是返回stdout
的'w'
模式
所以,有什么想法吗?另外,如果有更好的方法来流式传输二进制数据,而不使用stdout
,我也很乐意听听建议。
1 个回答
0
sys.stdout
其实就是一个变量,它指向和 sys.__stdout__
一样的东西。
所以,你只需要以二进制模式打开一个文件,把这个文件赋值给 sys.stdout
,然后就可以使用它了。如果你以后需要恢复正常的标准输出,可以用下面的代码来获取:
sys.stdout = sys.__stdout__