#python #struct #unpack
#python #struct #распаковать
Вопрос:
Это повторяющийся вопрос, но я не смог найти ответ
Я читаю двоичный файл в следующем формате (просто показываю одну из 3000 строк в шестнадцатеричном формате, как показано в sublime text):
0009 7f71 0009 b87b 0009 f24b 000a 2ce2
Я хочу прочитать его как кортеж из 4-байтовых целых чисел без знака
if filename:
with open(filename, mode='rb') as file:
fileData = file.read()
unsignedData = struct.unpack('I', fileData )
Однако я получаю следующую ошибку для последней строки в приведенном выше коде:
struct.error: unpack requires a buffer of 4 bytes
Как это исправить?
Комментарии:
1. Попробуйте использовать
struct.unpack('2I', fileData)
2. @martineau Как мне изменить порядковый номер между большим и маленьким порядковым номером?
3. Смотрите
struct
документацию модуля.
Ответ №1:
Декодирование нескольких целых чисел
Обычно io.RawIOBase.read
возвращается намного больше, чем 4 байта (это ограничено системным вызовом и / или размером файла).
С другой стороны, размер буфера в байтах должен соответствовать размеру, требуемому строкой формата to struct.unpack
.
Общая структура данных вашего файла неясна, но, например, для чтения 4 32-разрядных целых чисел без знака, закодированных в строчном порядке (предоставленные вами данные), вы должны разрезать буфер:
unsignedData = struct.unpack('4I', fileData[:16])
Декодирование потока
В случае, если вам нужно декодировать произвольно длинный поток целых чисел из вашего файла, есть несколько вариантов, в зависимости от ожидаемой длины данных.
Короткий поток
with open(filename, mode='rb') as fp:
fileData = fp.read()
n, r = divmod(len(fileData), struct.calcsize('I'))
assert r == 0, "Data length not a multiple of int size"
unsignedData = struct.unpack('I' * n, fileData)
Длинный поток
Вы могли бы использовать struct.iter_unpack
, но, вероятно, имеет смысл хранить большие данные int в array.array
or numpy.array
в любом случае.
Вот пример для массива NumPy:
import numpy
data = numpy.fromfile(filename, dtype='uint32')
Я оставлю загрузку в однородный массив данных Python в качестве упражнения для читателя (подсказка: array.fromfile
).
Комментарии:
1. Когда я открываю двоичный файл в sublime text, он показывает мне несколько строк в формате «0009 7f71 0009 b87b 0009 f24b 000a 2ce2». Я думаю, что эта строка представляет собой числа в шестнадцатеричном формате. В двоичном файле 3000 таких строк. Я хочу просто интерпретировать байты в файле как 4-байтовый unsigned int и заполнить их внутри кортежа
2. Итак, вы хотите интерпретировать весь файл как (поток) целых чисел?
3. ДА. Поток 4-байтовых целых чисел без знака
4. Хорошо, @nurabha, я расширил свой ответ, включив некоторые параметры декодирования потока.