Как считывать байты из файла в Python
Вопрос
Похожий на это вопрос, я пытаюсь прочитать заголовок тега ID3v2, и у меня возникают проблемы с пониманием того, как получить отдельные байты в python.
Сначала я прочитал все десять байт в строку.Затем я хочу разобрать отдельные фрагменты информации.
Я могу взять два символа номера версии в строке, но тогда я понятия не имею, как взять эти два символа и получить из них целое число.
Пакет struct, кажется, это то, что я хочу, но я не могу заставить его работать.
Вот мой код на данный момент (я очень новичок в python btw...so успокойся со мной):
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]
Вывод любых значений, за исключением, очевидно, дерьмовых, потому что они неправильно отформатированы.
Решение
Если у вас есть строка с 2 байтами, которую вы хотите интерпретировать как 16-битное целое число, вы можете сделать это с помощью:
>>> s = '\0\x02'
>>> struct.unpack('>H', s)
(2,)
Обратите внимание, что > используется для порядкового номера (наибольшая часть целого числа идет первой).Это формат, который используют теги id3.
Для других размеров целых чисел вы используете другие коды формата.например."i" для 32-битного целого числа со знаком.Подробности смотрите в справке (struct).
Вы также можете распаковать сразу несколько элементов.например, для 2 беззнаковых коротких замыканий, за которыми следует 32-битное значение со знаком:
>>> a,b,c = struct.unpack('>HHi', some_string)
Следуя вашему коду, который вы ищете (по порядку):
- строка из 3 символов
- 2 однобайтовых значения (основная и второстепенная версии)
- переменная flags размером в 1 байт
- величина длины 32 бита
Строка формата для этого будет выглядеть следующим образом:
ident, major, minor, flags, len = struct.unpack('>3sBBBI', ten_byte_string)
Другие советы
Я пытаюсь прочитать заголовок тега ID3v2
ФУ-у-у, там есть уже есть модуль для этого.
Я собирался порекомендовать struct
но потом вы сказали, что уже пробовали это.Попробуй это:
self.major_version = struct.unpack('H', self.whole_string[3:5])
Тот Самый pack()
функция преобразует типы данных Python в биты, и unpack()
функция преобразует биты в типы данных Python.