Запись двоичных данных в стандартный вывод с помощью IronPython - PullRequest
0 голосов
/ 31 июля 2010

У меня есть два скрипта 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, вы можете получить доступ к небуферизованным stdout через sys.stdout.buffer;это не доступно в 2.6
  • os.fdopen(sys.stdout.fileno(), 'wb', 0) просто возвращает stdout в 'w' режиме

Так что, есть идеи?Кроме того, если есть лучший способ потоковой передачи двоичных данных, в котором не используется stdout, я, безусловно, открыт для предложений.

1 Ответ

0 голосов
/ 31 июля 2010

sys.stdout - это просто переменная, которая указывает на то же самое, что и sys.__stdout__

Поэтому просто откройте файл в двоичном режиме, назначьте файл для sys.stdout и используйте его. Если вам когда-нибудь снова понадобится настоящий нормальный стандартный вывод, вы можете получить его с помощью

sys.stdout = sys.__stdout__
...