Подтвердить что ты не робот

Чтение двоичных данных из stdin

Можно ли читать 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.

Итак, я попытаюсь обновить свой оригинальный вопрос с некоторыми заметками о том, что я понял до сих пор.

4b9b3361

Ответ 1

Используйте -u переключатель командной строки, чтобы заставить Python 2 рассматривать stdin, stdout и stderr как двоичные небуферизованные потоки.

C:> type mydoc.txt | python.exe -u myscript.py

Ответ 2

Из документов (см. здесь):

Стандартные потоки находятся в текстовом режиме по умолчанию. Чтобы написать или прочитать двоичный файл данных к ним, используйте бинарный буфер. Например, чтобы написать байт в stdout, используйте sys.stdout.buffer.write(b'abc').

Но, как и в принятом ответе, вызов python с -u - это еще один параметр, который заставляет stdin, stdout и stderr быть полностью небуферизованными. Подробнее см. Справочную страницу python (1).

Дополнительную информацию о буферизации текста см. в документации на io и используйте sys.stdin.detach(), чтобы отключить буферизацию из Python.

Ответ 3

Вот окончательный вариант для совместимого с 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()

Ответ 4

Если вам все еще нужно... Этот простой тест, который я использовал для чтения двоичного файла, содержащего символ 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.

Ответ 5

Вы можете выполнить небуферизованное чтение с помощью:

os.read(0, bytes_to_read)

где 0 - дескриптор файла для стандартного ввода

Ответ 6

import sys

data = sys.stdin.read(10) # Read 10 bytes from stdin

Если вам нужно интерпретировать двоичные данные, используйте модуль struct.