python - Leyendo datos binarios de stdin




python-2.x (5)

¿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 que no estén contaminados.

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 programa Jython de Eclipse

Parte de esa pregunta fue respondida en esta question .

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


Answers

De los documentos (ver here ):

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 stdin, stdout y stderr a ser totalmente sin búfer. Consulte la página de manual de python (1) para obtener más información.

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.



import sys

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

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


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

En su segundo ejemplo (con scanf ()), la razón por la que esto es aún más lento podría deberse a que scanf ("% s") analiza la cadena y busca cualquier char de espacio (espacio, tabulador, nueva línea).

También, sí, CPython hace algo de almacenamiento en caché para evitar lecturas de disco duro.





python python-2.x