Чтение целых чисел из двоичного файла в Python
Я пытаюсь прочитать файл BMP в Python. Я знаю первые два байта
указать фирму BMP. Следующие 4 байта - это размер файла. Когда я буду excecute:
fin = open("hi.bmp", "rb")
firm = fin.read(2)
file_size = int(fin.read(4))
Я получаю
ValueError: недействительный литерал для int() с базой 10: 'F #\x13'
Что я хочу сделать, это прочитать эти четыре байта как целое число... Кажется, что Python читает их как символы и возвращает строку, которая не может быть преобразована в целое. Как я могу сделать это правильно?
Ответы
Ответ 1
Метод read
возвращает последовательность байтов в виде строки. Чтобы преобразовать из строковой байтовой последовательности в двоичные данные, используйте встроенный модуль struct
: http://docs.python.org/library/struct.html.
import struct
print(struct.unpack('i', fin.read(4)))
Обратите внимание, что unpack
всегда возвращает кортеж, поэтому struct.unpack('i', fin.read(4))[0]
дает целочисленное значение, которое вы после.
Вероятно, вы должны использовать строку формата '<i'
(< - это модификатор, который указывает порядок байтов и стандартный размер и выравнивание по младшему порядку - по умолчанию используется порядок, размер и выравнивание байтов платформы). Согласно спецификации формата BMP, байты должны быть записаны в порядке байтов Intel/little-endian.
Ответ 2
Альтернативным методом, который не использует "struct.unpack()", было бы использовать NumPy:
import numpy as np
f = open("file.bin", "r")
a = np.fromfile(f, dtype=np.uint32)
'dtype' представляет тип данных и может быть int #, uint #, float #, complex # или определяемым пользователем типом. См. numpy.fromfile
.
Лично предпочитайте использовать NumPy для работы с данными массива/матрицы, поскольку это намного быстрее, чем использование списков Python.
Ответ 3
Кроме struct
вы также можете использовать модуль array
import array
values = array.array('l') # array of long integers
values.read(fin, 1) # read 1 integer
file_size = values[0]
Ответ 4
Когда вы читаете двоичный файл, вам нужно распаковать его в целое число, поэтому используйте модуль struct для этого
import struct
fin = open("hi.bmp", "rb")
firm = fin.read(2)
file_size, = struct.unpack("i",fin.read(4))
Ответ 5
С Python 3.2+ вы также можете выполнить это, используя метод from_bytes
:
file_size = int.from_bytes(fin.read(2), byteorder='big')
Обратите внимание, что для этой функции требуется указать, закодировано ли число в формате большой или малой длины, поэтому вам нужно будет определить конечный результат, чтобы убедиться, что он работает правильно.