Comment lire des octets à partir d'un fichier en Python
Question
Semblable à la cette question, j'essaie de lire dans un en-tête de balise ID3v2 et je ne parviens pas à comprendre comment obtenir des octets individuels en python.
J'ai d'abord lu les dix octets dans une chaîne. Je souhaite ensuite analyser les informations individuelles.
Je peux saisir les deux caractères de numéro de version dans la chaîne, mais je ne sais pas comment prendre ces deux caractères et en obtenir un entier.
Le package struct semble être ce que je veux, mais je ne peux pas le faire fonctionner.
Voici mon code pour l'instant (je suis très nouveau en python ... alors prenez-le doucement pour moi):
def __init__(self, ten_byte_string):
self.whole_string = ten_byte_string
self.file_identifier = self.whole_string[:3]
self.major_version = struct.pack('x', self.whole_string[3:4]) #this
self.minor_version = struct.pack('x', self.whole_string[4:5]) # and this
self.flags = self.whole_string[5:6]
self.len = self.whole_string[6:10]
Imprimer n'importe quelle valeur, sauf que c'est évidemment de la merde, car elles ne sont pas formatées correctement.
La solution
Si vous avez une chaîne de 2 octets que vous souhaitez interpréter comme un entier de 16 bits, vous pouvez le faire en:
>>> s = '\0\x02'
>>> struct.unpack('>H', s)
(2,)
Notez que le > est pour big-endian (la plus grande partie de l'entier vient en premier). C'est le format utilisé par les tags id3.
Pour les autres tailles de nombre entier, vous utilisez des codes de format différents. par exemple. " i " pour un entier signé de 32 bits. Voir help (struct) pour plus de détails.
Vous pouvez également décompresser plusieurs éléments à la fois. par exemple, pour 2 courts-circuits non signés, suivis d'une valeur 32 bits signée:
>>> a,b,c = struct.unpack('>HHi', some_string)
En fonction de votre code, vous recherchez (dans l'ordre):
- une chaîne de 3 caractères
- 2 valeurs à un octet (version majeure et mineure)
- une variable d'indicateur sur 1 octet
- une quantité de longueur 32 bits
La chaîne de format pour cela serait:
ident, major, minor, flags, len = struct.unpack('>3sBBBI', ten_byte_string)
Autres conseils
J'essaie de lire un en-tête de balise ID3v2
FWIW, il existe un module pour cela.
J'allais recommander le paquet struct
, mais vous avez ensuite dit que vous l'aviez essayé. Essayez ceci:
self.major_version = struct.unpack('H', self.whole_string[3:5])
La fonction pack ()
convertit les types de données Python en bits et la fonction unpack ()
convertit les bits en types de données Python.