使用IronPython向标准输出写入二进制数据

0 投票
1 回答
840 浏览
提问于 2025-04-16 02:05

我有两个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__

撰写回答