2011-05-25 82 views
4

是否有任何好的Python解决方案,如Ruby的BinData用于读取用户定义的二进制文件/流格式?如果不是的话,那么在使用struct模块之外,Python中的首选方法是什么?在Python中读取结构二进制数据?

我有一个存储事件“记录”的二进制文件。记录的大小是动态的,所以我必须读取每条记录的前几个字节以确定记录长度和记录类型。不同的记录类型将有不同的字节布局。例如,“警告”类型的记录可能包含三个4字节整数,后跟一个128字节值,而类型为“info”的记录可能只有五个4字节整数。

这将是很好的定义不同的记录类型及其结构的方式,我可以简单地将二进制blob传递给某些东西,并处理其余的东西(对象生成等)。简而言之,您定义的模板/映射关于如何解释二进制数据。

+2

曾经看过['struct'](http://docs.python.org/library/struct.html)模块? – Santa 2011-05-25 23:16:02

+0

是的,但乍一看,我不知道如何指定像BinData这样的自定义结构。 – dj29 2011-05-25 23:23:10

+1

你需要做什么,结构模块不能做什么? – Keith 2011-05-25 23:36:02

回答

3

也许您在寻找Construct,纯粹的Python 2二进制解析库?

3

Python的结构模块的工作原理是这样的:

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

-1

我想给怎么办阅读蟒蛇的例子。

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格式之间的映射。