Recherche/lecture de données binaires en Python
Je suis en train de lire dans un fichier binaire (format jpg dans ce cas), et ont besoin de trouver des valeurs dans ce fichier. Pour ceux que cela intéresse, le fichier binaire est un jpg, et je suis tenté de prendre ses dimensions par la recherche de la structure binaire comme détaillé ici.
J'ai besoin de trouver FFC0 dans le binaire de données, passez à l'avance un certain nombre d'octets, et ensuite de lire les 4 octets (ce qui devrait me donner les dimensions de l'image).
Ce qui est une bonne façon de chercher la valeur dans les données binaires? Est-il un équivalent de "trouver", ou quelque chose comme re?
avez-vous jamais regardé dans imagick? Autant que je me souvienne il y a aussi une bibliothèque python pour elle.
Je l'ai et il fonctionne très bien, mais c'est très lourd pour juste trouver les dimensions du fichier.
vous devez utiliser un module approprié pour quelque chose comme ceci snippets.dzone.com/posts/show/1021
Je l'ai et il fonctionne très bien, mais c'est très lourd pour juste trouver les dimensions du fichier.
vous devez utiliser un module approprié pour quelque chose comme ceci snippets.dzone.com/posts/show/1021
OriginalL'auteur Parand | 2010-07-10
Vous devez vous connecter pour publier un commentaire.
Vous pouvez charger le fichier dans une chaîne de caractères et la recherche d'une chaîne pour la séquence d'octets
0xffc0
à l'aide de lastr.find()
méthode. Il fonctionne pour n'importe quelle séquence d'octets.Le code pour faire cela dépend de plusieurs choses. Si vous ouvrez le fichier en mode binaire et vous êtes à l'aide de Python 3 (qui sont probablement les meilleures pratiques pour ce scénario), vous aurez besoin de recherche pour une chaîne d'octets (par opposition à une chaîne de caractères), ce qui signifie que vous avez à préfixe de la chaîne de
b
.Si vous ouvrez le fichier en mode texte en Python 3, vous auriez à la recherche d'une chaîne de caractères:
s'il n'y a pas de raison particulière de le faire. Il n'est pas un avantage par rapport à la précédente, et si vous êtes sur une plate-forme qui traite les fichiers binaires et les fichiers de texte différemment (par exemple Windows), il y a une chance cela va causer des problèmes.
Python 2 ne fait pas la distinction entre les chaînes d'octets et les chaînes de caractères, donc si vous utilisez cette version, il n'a pas d'importance si vous d'inclure ou d'exclure les
b
dansb'\xff\xc0'
. Et si votre plate-forme de traite des fichiers binaires et les fichiers de texte à l'identique (par exemple, Mac ou Linux), il n'a pas d'importance si vous utilisez'r'
ou'rb'
que le mode de fichier. Mais je voudrais encore vous recommandons d'utiliser quelque chose comme le premier exemple de code ci-dessus juste pour la compatibilité ascendante, - dans le cas où vous faites jamais passer à Python 3, c'est une chose de moins à corriger.Je doute que c'est tellement grand que ça va être un problème.
Depuis que je suis seulement à la recherche de la première image, je vais probablement être en mesure de lire une petite partie du fichier et de processus qui, au lieu de lire le fichier en entier.
bon point, mais je tiens à souligner que vous pouvez faire exactement ce que Parand dit, il suffit de lire les N premiers octets et de la recherche. Si vous n'avez plus à rechercher tout d'un fichier de grande taille pour une séquence d'octets, il pourrait être fait de manière itérative, de sorte que vous n'avez pas à garder tout ça en mémoire à la fois, mais le code sera un peu plus impliqué, et je ne pense pas qu'il serait nécessaire d'entrer dans les ici.
Exactement. Je viens de dire qu'il serait mieux de lire/scan en petits morceaux.
OriginalL'auteur David Z
La bitstring module a été conçu pour à peu près cet effet. Pour votre cas, le code suivant (dont je n'ai pas testé) devrait aider à comprendre:
Bits.find
renvoie juste un booléen et définit laBits.bytepos
attribut? Peut-être dans la documentation du module, vous devriez avertir quebitstring
n'est pas thread-safe (pas que cela importe, dans cette réponse, bien sûr).Oui, vous avez un bon point. Je ne trouve pas ça surprenant que la mutation des méthodes ou des méthodes de lecture ne sont pas thread-safe, mais à l'aide de "trouver" un peu-sage immuable de l'objet peut être raisonnablement attendu. Pour être honnête, il n'est jamais apparu avant, mais c'est quelque chose à penser...
Juste une idée:
find
pourrait retourne un objet contenant toutes les informations nécessaires à lare.match
etre.search
. Vous pourriez avoir ce “BitMatch” class être une sous-classe debool
, pour assurer la compatibilité ascendante.Merci, c'est une idée raisonnable bien que je suis dans une bonne position pour briser la compatibilité descendante légèrement et peut-être suffit-il de retour de la position du bit comme un seul élément d'un tuple si trouvé ou un tuple vide si elle ne trouve pas. Je suppose que rien de mieux que de retourner -1 si non trouvé 🙂
OriginalL'auteur Scott Griffiths
Au lieu de lire tout le fichier en mémoire, à la recherche, et puis de l'écriture d'un nouveau fichier sur le disque, vous pouvez utiliser le mmap module pour cela. mmap sera pas stocker la totalité du fichier en mémoire et il permet en cours de modification.
OriginalL'auteur synthesizerpatel
La
re
module ne travailler avec les deux cordes et binaire de données (str
en Python 2 etbytes
en Python 3), de sorte que vous pouvez l'utiliser aussi bien commestr.find
pour votre tâche.OriginalL'auteur Andrey Vlasovskikh
Bien, évidemment, il est PIL L'Image du module a la taille comme un attribut. Si vous êtes désireux d'obtenir la taille exactement comment vous suggérer et sans charger le fichier que vous allez avoir à aller ligne par ligne. Pas la plus belle façon de le faire, mais il pourrait fonctionner.
OriginalL'auteur fridder
La
find()
méthode doit être utilisée uniquement si vous avez besoin de connaître la position des sous, si pas, vous pouvez utiliser lein
de l'opérateur, par exemple:OriginalL'auteur kenorb
En Python 3.x vous pouvez rechercher un octet de la chaîne par une autre chaîne d'octets comme ceci:
OriginalL'auteur caleb
Pour Python >=3.2:
OriginalL'auteur kissson