Leyendo datos binarios de stdin

¿Es posible leer stdin como datos binarios en Python 2.6? ¿Si es así, cómo?

Veo en la documentación de Python 3.1 que esto es bastante simple, pero las facilidades para hacer esto en 2.6 no parecen estar ahí.

Si los métodos descritos en 3.1 no están disponibles, ¿hay alguna forma de cerrar la entrada estándar y volver a abrir en modo binario?

Actualizar

Para que quede claro, estoy usando ‘tipo’ en un shell de MS-DOS para canalizar el contenido de un archivo binario a mi código de Python. Esto debería ser el equivalente de un comando ‘cat’ de Unix, por lo que yo entiendo. Pero cuando pruebo esto, siempre obtengo un byte menos que el tamaño de archivo esperado.

Actualización # 2

En primer lugar, gracias por todas las respuestas. Estoy trabajando lentamente hacia una solución real y utilizable aquí. Al final, todavía estoy intentando crear un archivo JAR autónomo que ejecute mi código de Python y pase automáticamente todos los argumentos de la línea de comandos sin mancha.

La razón por la que tomo la ruta Java / JAR / Jython es porque una de mis bibliotecas externas principales solo está disponible como Java JAR. Pero desafortunadamente, comencé mi trabajo como Python. Podría haber sido más fácil convertir mi código a Java hace un tiempo, pero como se suponía que todo esto era compatible, pensé que intentaría transportarlo y demostrar que podía hacerse.

En caso de que alguien se lo pregunte, esto también está relacionado con la pregunta que hice hace unos días.

Empaquetando y desplegando un progtwig Jython de Eclipse

Parte de esa pregunta fue respondida en esta pregunta .

Así que intentaré actualizar mi pregunta original con algunas notas sobre lo que he descubierto hasta ahora.

Use el interruptor de la línea de comandos -u para forzar a Python 2 a tratar stdin, stdout y stderr como flujos binarios sin búfer.

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

De los documentos (ver aquí ):

Las transmisiones estándar están en modo de texto por defecto. Para escribir o leer datos binarios a estos, use el búfer binario subyacente. Por ejemplo, para escribir bytes en stdout, use sys.stdout.buffer.write(b'abc') .

Pero, como en la respuesta aceptada, invocar python con a -u es otra opción que obliga a que stdin, stdout y stderr sean totalmente sin búfer. Vea la página de manual de python (1) para más detalles.

Consulte la documentación en io para obtener más información sobre el búfer de texto y use sys.stdin.detach() para deshabilitar el búfer desde Python.

Aquí está el corte final para el código compatible con Linux / Windows Python 2/3 para leer datos de stdin sin corrupción:

 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() 

Si aún necesitas esto … Esta simple prueba que he usado para leer un archivo binario que contiene caracteres 0x1A en medio

 import os, sys, msvcrt msvcrt.setmode (sys.stdin.fileno(), os.O_BINARY) s = sys.stdin.read() print len (s) 

Los datos de mi archivo de prueba fueron:

 0x23, 0x1A, 0x45 

Sin configurar stdin en modo binario, esta prueba imprime 1 tan pronto como trata a 0x1A como EOF. Por supuesto, funciona solo en Windows, porque depende del módulo msvcrt.

Puedes realizar una lectura sin búfer con:

os.read(0, bytes_to_read)

siendo 0 el descriptor de archivo para stdin

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

Si necesita interpretar datos binarios, use el módulo de struct .