Подтвердить что ты не робот

Чтение целых чисел из двоичного файла в 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 читает их как символы и возвращает строку, которая не может быть преобразована в целое. Как я могу сделать это правильно?

4b9b3361

Ответ 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')

Обратите внимание, что для этой функции требуется указать, закодировано ли число в формате большой или малой длины, поэтому вам нужно будет определить конечный результат, чтобы убедиться, что он работает правильно.