Чтение структуры двоичных данных в Python? - PullRequest
4 голосов
/ 26 мая 2011

Существуют ли хорошие решения Python, такие как BinData от Ruby для чтения пользовательских двоичных форматов файлов / потоков? Если нет, то каков предпочтительный способ сделать это в Python, кроме использования struct module?

У меня есть бинарный файл, в котором хранятся «записи» событий. Записи имеют динамический размер, поэтому я должен прочитать первые несколько байтов каждой записи, чтобы определить длину и тип записи. Различные типы записей будут иметь разную структуру байтов. Например, запись типа «предупреждение» может содержать три 4-байтовых числа, за которыми следует 128-байтовое значение, тогда как запись типа «информация» может иметь только пять 4-байтовых числа.

Было бы неплохо определить различные типы записей и их структуры таким образом, чтобы я мог просто передать двоичный двоичный объект чему-либо и обработать остальное (генерация объекта и т. Д.). Короче говоря, ваши определяющие шаблоны / карты о том, как интерпретировать двоичные данные.

Ответы [ 4 ]

3 голосов
/ 26 мая 2011

Может быть, вы ищете Construct , двоичную библиотеку Pars 2 & 3 для чистого анализа Python?

3 голосов
/ 26 мая 2011

Python-модуль struct работает следующим образом:

record_header = struct.Struct("<cb") 
warning = struct.Struct("<iii128")
info = struct.Struct("<iiiii")

while True:
    header_text = input.read(record_header.size)
    # file is empty
    if not header_text:
       break
    packet_type, extra_data = record_header.unpack(header_text)
    if packet_type == 'w':
        warning_data = warning.unpack( input.read(warning.size) )
    elif packet_type == 'i':
        info_data = info.unpack( input.read(info.size) )

Подробности см. В документации: http://docs.python.org/library/struct.html

2 голосов
/ 26 мая 2011

Модуль struct, вероятно, будет работать, но вы также можете использовать привязки python для буферов протокола Google .

0 голосов
/ 28 января 2014

Я хотел бы привести пример того, как читать в Python.

typedef struct {
    ID             chunkname;
    long           chunksize;

    /* Note: there may be additional fields here, depending upon your data. */

} Chunk;

Как вы читаете эту структуру данных из файла в Python?Вот один из способов:

class Chunk:
def __init__(self, file, align=True, bigendian=True, inclheader=False):
    import struct
    self.closed = False
    self.align = align      # whether to align to word (2-byte) boundaries
    if bigendian:
        strflag = '>'
    else:
        strflag = '<'
    self.file = file
    self.chunkname = file.read(4)
    if len(self.chunkname) < 4:
        # you need to take care of end of file
        raise EOFError
    try:
        # you could use unpack
        # http://docs.python.org/2/library/struct.html#format-characters
        # here 'L' means 'unsigned long' 4 standard size
        self.chunksize = struct.unpack(strflag+'L', file.read(4))[0]
    except struct.error:
        # you need to take care of end of file
        raise EOFError
    if inclheader:
        self.chunksize = self.chunksize - 8 # subtract header
    self.size_read = 0
    try:
        self.offset = self.file.tell()
    except (AttributeError, IOError):
        self.seekable = False
    else:
        self.seekable = True

Итак, вам необходимо понять соответствие между структурой c и форматом struct.unpack () http://docs.python.org/2/library/struct.html#format-characters.

...