Lecture de données binaires à partir de stdin
Est-il possible de lire stdin en tant que données binaires dans Python 2.6? Si oui, comment?
Je vois dans la documentation Python 3.1 que c'est assez simple, mais les facilités pour le faire dans 2.6 ne semblent pas être là.
Si les méthodes décrites dans 3.1 ne sont pas disponibles, existe-t-il un moyen de fermer stdin et de rouvrir en mode binaire?
Mise à Jour
Juste pour être clair, j'utilise 'type' dans un shell MS-DOS Pour diriger le contenu d'un fichier binaire vers mon python code. Cela devrait être L'équivalent D'une commande Unix 'cat', pour autant que je comprends. Mais quand je teste cela, je reçois toujours un octet de moins que la taille de fichier attendue.
Mise à Jour #2
Tout d'Abord, merci pour toutes les réponses. Je travaille lentement vers une solution réelle et utilisable ici. En fin de compte, j'essaie toujours de construire un fichier JAR autonome qui exécute mon code Python en passant automatiquement par tous les arguments de ligne de commande non tachés.
La raison Je vais la route Java/JAR/Jython est parce que l'une de mes principales bibliothèques externes est uniquement disponible en tant que JAR Java. Mais malheureusement, j'avais commencé mon travail en tant que Python. Il aurait pu être plus facile de convertir mon code en Java il y a un moment, mais comme tout cela était censé être compatible, j'ai pensé que j'essaierais de le faire et de prouver que cela pouvait être fait.
Au cas où quelqu'un se poserait la question, cela est également lié à la question que j'ai posée il y a quelques jours.
Conditionnement et déploiement D'un programme Jython à partir D'Eclipse
Une partie de cette question a été répondue dans cette question .
Donc, je vais essayer de mettre à jour ma question originale avec quelques notes sur ce que j'ai compris jusqu'à présent.
5 réponses
Utilisez le -u
command line switch pour forcer Python 2 à traiter stdin, stdout et stderr comme des flux binaires non tamponnés.
C:> type mydoc.txt | python.exe -u myscript.py
Des documents (voir ici):
Les flux standard sont en mode texte par défaut. Pour écrire ou lire binaire données à ceux-ci, utilisez le sous-jacent buffer binaire. Par exemple, pour écrire octets vers stdout, utilisez
sys.stdout.buffer.write(b'abc')
.
Mais, comme dans la réponse acceptée, invoquer python avec un -u
est une autre option qui force stdin, stdout et stderr à être totalement non tamponnés. Voir la page de manuel python(1) pour plus de détails.
Voir la documentation sur io
pour plus d'informations sur la mise en mémoire tampon de texte, et utilisez sys.stdin.detach()
pour désactiver la mise en mémoire tampon à partir de Python.
Voici la coupe finale pour le code compatible Linux / Windows Python 2/3 pour lire les données de stdin sans corruption:
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 vous en avez encore besoin... Ce test simple que j'ai utilisé pour lire le fichier binaire qui contient 0x1a caractère entre
import os, sys, msvcrt
msvcrt.setmode (sys.stdin.fileno(), os.O_BINARY)
s = sys.stdin.read()
print len (s)
Mes données de fichier de test étaient:
0x23, 0x1A, 0x45
Sans mettre stdin en mode binaire, ce test imprime 1 dès qu'il traite 0x1A comme EOF. Bien sûr, cela fonctionne uniquement sur windows, car cela dépend du module msvcrt.
import sys
data = sys.stdin.read(10) # Read 10 bytes from stdin
Si vous avez besoin d'interpréter des données binaires, utilisez le struct
module.