Ответ 1
Используйте -u
переключатель командной строки, чтобы заставить Python 2 рассматривать stdin, stdout и stderr как двоичные небуферизованные потоки.
C:> type mydoc.txt | python.exe -u myscript.py
Можно ли читать stdin как двоичные данные в Python 2.6? Если да, то как?
Я вижу в документации Python 3.1, что это довольно просто, но возможности для этого в 2.6 не кажутся есть.
Если методы, описанные в 3.1, недоступны, существует ли способ закрыть stdin и повторно открыть в двоичном режиме?
Обновление
Просто, чтобы быть ясным, я использую "тип" в оболочке MS-DOS, чтобы передать содержимое двоичного файла в код моего питона. Насколько я понимаю, это должно быть эквивалентом команды "cat" Unix. Но когда я проверяю это, я всегда получаю на один байт меньше ожидаемого размера файла.
Обновление # 2
Прежде всего, спасибо за все ответы. Я медленно работаю над настоящим, полезным решением. В конце концов, я все еще пытаюсь создать автономный JAR файл, который выполняет мой код Python, автоматически проходящий через все аргументы командной строки, не испорченные.
Причина, по которой я иду по маршруту Java/JAR/Jython, заключается в том, что одна из моих основных внешних библиотек доступна только как Java JAR. Но, к сожалению, я начал свою работу как Python. Возможно, было проще конвертировать мой код в Java некоторое время назад, но, поскольку этот материал должен был быть совместимым, я решил, что попробую проехать через него и доказать, что это можно сделать.
В случае, если кто-то задавался вопросом, это также связано с вопросом, который я задал несколько дней назад.
Упаковка и развертывание программы Jython из Eclipse
На этот вопрос ответили question.
Итак, я попытаюсь обновить свой оригинальный вопрос с некоторыми заметками о том, что я понял до сих пор.
Используйте -u
переключатель командной строки, чтобы заставить Python 2 рассматривать stdin, stdout и stderr как двоичные небуферизованные потоки.
C:> type mydoc.txt | python.exe -u myscript.py
Из документов (см. здесь):
Стандартные потоки находятся в текстовом режиме по умолчанию. Чтобы написать или прочитать двоичный файл данных к ним, используйте бинарный буфер. Например, чтобы написать байт в stdout, используйте
sys.stdout.buffer.write(b'abc')
.
Но, как и в принятом ответе, вызов python с -u
- это еще один параметр, который заставляет stdin, stdout и stderr быть полностью небуферизованными. Подробнее см. Справочную страницу python (1).
Дополнительную информацию о буферизации текста см. в документации на io
и используйте sys.stdin.detach()
, чтобы отключить буферизацию из Python.
Вот окончательный вариант для совместимого с 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()
Если вам все еще нужно... Этот простой тест, который я использовал для чтения двоичного файла, содержащего символ 0x1A между
import os, sys, msvcrt
msvcrt.setmode (sys.stdin.fileno(), os.O_BINARY)
s = sys.stdin.read()
print len (s)
Мои данные тестового файла:
0x23, 0x1A, 0x45
Без установки stdin в двоичный режим этот тест печатает 1, как только он обрабатывает 0x1A как EOF. Конечно, он работает только с окнами, потому что зависит от модуля msvcrt.
Вы можете выполнить небуферизованное чтение с помощью:
os.read(0, bytes_to_read)
где 0 - дескриптор файла для стандартного ввода
import sys
data = sys.stdin.read(10) # Read 10 bytes from stdin
Если вам нужно интерпретировать двоичные данные, используйте модуль struct
.