【发布时间】:2010-07-31 06:00:27
【问题描述】:
我有两个 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 使用二进制模式(我假设鉴于 cmd.exe 使用 CP437,不可能让它使用 ASCII 编码),它将得到解决。这就是我卡住的地方;我找不到任何方法来做到这一点。
我发现的一些潜在解决方案不起作用:
- 运行
ipy -u似乎没有任何效果(我还测试了它是否会导致打印 Unix 样式的换行符;它不会,所以我怀疑-u不适用于IronPython) - 我无法使用 this solution,因为 IronPython 不支持
msvcrt - 使用 Python 3.x,您可以通过
sys.stdout.buffer访问无缓冲的stdout;这在 2.6 中不可用 -
os.fdopen(sys.stdout.fileno(), 'wb', 0)只是在'w'模式下返回stdout
是的,有什么想法吗?此外,如果有更好的不使用stdout 的二进制数据流传输方式,我当然愿意接受建议。
【问题讨论】:
标签: python character-encoding ironpython stdout