2008-09-29 18 views
8

? Similar a la pregunta this, estoy tratando de leer en un encabezado de etiqueta ID3v2 y tengo problemas para averiguar cómo obtener bytes individuales en python.¿Cómo se pueden leer bytes del archivo en Python

Primero leí los diez bytes en una cadena. Entonces quiero analizar las piezas individuales de información.

Puedo agarrar los dos caracteres de número de versión en la cadena, pero no tengo idea de cómo tomar esos dos caracteres y obtener un número entero de ellos.

El paquete struct parece ser lo que quiero, pero no puedo hacer que funcione.

Aquí está mi código tan lejos (yo soy muy nuevo a Python por cierto ... así que tomarlo con calma en mí):

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] 

Impresión a cabo cualquier valor excepto obviamente basura porque no tienen el formato correctamente.

Respuesta

16

Si usted tiene una cadena, con 2 bytes que se desea interpretar como un entero de 16 bits, puede hacerlo utilizando:

>>> s = '\0\x02' 
>>> struct.unpack('>H', s) 
(2,) 

Tenga en cuenta que la> es para big-endian (la parte más grande del entero viene primero). Este es el formato que usan las etiquetas ID3.

Para otros tamaños de números enteros, utiliza códigos de formato diferentes. p.ej. "i" para un entero de 32 bits con signo. Ver ayuda (struct) para más detalles.

También puede descomprimir varios elementos a la vez. por ejemplo, durante 2 unsignedshorts, seguido por un valor de 32 bits con signo:

>>> a,b,c = struct.unpack('>HHi', some_string) 

A juzgar por su código, que está buscando (en orden):

  • una cadena de 3 caracteres
  • 2 individuales valores de bytes (versión mayor y menor)
  • unas banderas 1 byte variables
  • una cantidad de 32 bits de longitud

La cadena de formato para esto sería:

ident, major, minor, flags, len = struct.unpack('>3sBBBI', ten_byte_string) 
2

Yo iba a recomendar el paquete struct pero luego dijiste que lo habías probado. Prueba esto:

self.major_version = struct.unpack('H', self.whole_string[3:5]) 

La función pack() convers tipos de datos de Python a los bits, y la función unpack() convierte bits para los tipos de datos de Python.

+0

para 'H', tendrá que usar un corte de 2 bytes. – Brian

+0

Tienes razón, pasé por alto eso. Arreglaré mi ejemplo para que funcione, pero la tuya es una mejor respuesta de todos modos. –

4

¿Por qué escribir su propio? (Suponiendo que no haya verificado estas otras opciones). Hay un par de opciones para leer en la información de la etiqueta ID3 de MP3 en Python. Mira mi answer en this pregunta.

+1

Los vi. Pero esto es en realidad para un proyecto para la escuela y decidimos que escribiríamos nuestro propio analizador. – jjnguy

2

Estoy tratando de leer en un encabezado ID3v2

Fwiw, hay already a module para esto.

Cuestiones relacionadas