Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将二进制文件读入结构_Python_Binaryfiles - Fatal编程技术网

Python 将二进制文件读入结构

Python 将二进制文件读入结构,python,binaryfiles,Python,Binaryfiles,我有一个已知格式/结构的二进制文件 如何将所有二进制数据读入结构的数组中 类似(在伪代码中) 编辑: 迄今为止的解决办法: data = [] fmt = '=iiiii256i' fmt_s = '=iiiii' fmt_spec = '256i' struct_size = struct.calcsize(fmt) for i in range(struct_size, len(bytes)-struct_size, struct_size): dat1= list(str

我有一个已知格式/结构的二进制文件

如何将所有二进制数据读入结构的数组中

类似(在伪代码中)

编辑:

迄今为止的解决办法:

data = []

fmt   = '=iiiii256i'
fmt_s = '=iiiii'
fmt_spec = '256i'

struct_size = struct.calcsize(fmt)

for i in range(struct_size, len(bytes)-struct_size, struct_size):
    dat1= list(struct.unpack(fmt_s, bytes[i-struct_size:i-1024]))
    dat2= list(struct.unpack(fmt_spec, bytes[i-1024:i]))
    dat1.append(dat2)
    data.append(dat1)
使用;您需要以该库中记录的字符串格式定义类型:

struct.unpack('=HHf255s', bytes)
上面的示例需要本机字节顺序、两个无符号短字符、一个浮点和255个字符的字符串

要循环一个已经完全读取的
字节
字符串,我将使用
itertools
;我在这里采用了一个方便的方法:

from itertools import izip_longest, imap
from struct import unpack, calcsize

fmt_s = '=5i'
fmt_spec = '=256i'
size_s = calcsize(fmt_s)
size = size_s + calcsize(fmt_spec)

def chunked(iterable, n, fillvalue=''):
    args = [iter(iterable)] * n
    return imap(''.join, izip_longest(*args, fillvalue=fillvalue))

data = [unpack(fmt_s, section[:size_s]) + (unpack(fmt_spec, section[size_s:]),)
    for section in chunked(bytes, size)]
    
这将生成元组而不是列表,但如果必须执行以下操作,则可以很容易地进行调整:

data = [list(unpack(fmt_s, section[:size_s])) + [list(unpack(fmt_spec, section[size_s:]))]
    for section in chunked(bytes, size)]
添加评论

import struct 
首先,将二进制文件读入数组

mbr = file('mbrcontent', 'rb').read() 
所以你们可以从数组中取出一些片段

partition_table = mbr[446:510] 
然后将其解包为整数

signature = struct.unpack('<H', mbr[510:512])[0] 

signature=struct.unpack(“实际上,看起来您正在尝试读取列表(或数组)在Python中执行此操作的惯用方法是使用
struct
模块并在循环中调用固定次数(如果您事先知道它们的数量),或者直到到达文件末尾并将结果存储在
列表中。下面是后者的一个示例:

import struct

struct_fmt = '=5if255s' # int[5], float, byte[255]
struct_len = struct.calcsize(struct_fmt)
struct_unpack = struct.Struct(struct_fmt).unpack_from

results = []
with open(filename, "rb") as f:
    while True:
        data = f.read(struct_len)
        if not data: break
        s = struct_unpack(data)
        results.append(s)
同样的结果也可以使用一个简短的助手(即下面的
read_chunks()
)更简洁地获得:

更新

事实上,您不需要如上所示显式定义助手函数,因为您可以使用Python的内置函数在列表中动态创建所需的对象,如下所示:

from functools import partial

with open(filename, "rb") as f:
    results = [struct_unpack(chunk) for chunk in iter(partial(f.read, struct_len), b'')]
导入操作系统,重新
导入功能工具
导入ctypes
从ctypes导入字符串、byref、sizeof、cast、指针、指针、创建字符串缓冲区、memmove
将numpy作为np导入
作为pd进口熊猫
类_StructBase(ctypes.Structure):
__类型=0
_字段\=[]
@类方法
def偏移量(cls,字段):
模式='(?P\w+)\[(?P\d+)\]
mat=重新匹配(模式、字段)
如有必要:
fields=dict(cls.fields())
f=mat.groupdict()['field']
idx=mat.groupdict()['idx']
返回cls.Offsetof(f)+int(idx)*ctypes.sizeof(字段[字段])
其他:
返回getattr(cls,字段).offset
@类方法
def数据类型(cls):
地图={
ctypes.c_字节:np.byte,
ctypes.c_ubyte:np.ubyte,
ctypes.c_char:np.ubyte,
ctypes.c_int8:np.int8,
c类型c_int16:np.int16,
ctypes.c_int32:np.int32,
ctypes.c_int64:np.int64,
c类型c_uint8:np.uint8,
ctypes.c_uint16:np.uint16,
c类型c_uint32:np.uint32,
c类型c_uint64:np.uint64,
ctypes.c_float:np.float32,
ctypes.c_double:np.64,
}
res=[]
对于cls.Fields()中的k,v:
如果hasattr(v,'u长度'):
如果v._type.=ctypes.c_char:
对于范围内的i(v.。_长度):
res.append((k,map[v],cls.Offsetof(k)))
其他:
res.append((k,'S%d'%v.\u长度,cls.Offsetof(k)))
其他:
res.append((k,map[v],cls.Offsetof(k)))
res=pd.DataFrame(res,columns=['name','format','offset'])
返回np.dtype({
“名称”:res[“名称”],
“格式”:res[“格式”],
“偏移量”:res[“偏移量”],
})
@类方法
def属性(cls):
字段=cls.\u字段_
res=[]
对于attr,字段中的tp:
如果str(tp).find(''u数组'')>0和str(tp).find('char\u数组'')<0:
对于范围内的i(tp.\U长度):
res.append((attr+'[%s]'%str(i),tp.\u类型)
其他:
res.append((attr,tp))
返回res
@类方法
def字段(cls,notype=False):
res=[cls.Attr()]
cur_cls=cls
尽管如此:
cur_cls=cur_cls.\uuuuuu base\uuuuuuu[0]
如果cur_cls==ctypes.Structure:
打破
res.append(cur_cls.Attr())
如果不输入:
返回[k代表k,v在functools.reduce(list.\uu添加\uuuu,反转(res),[])]
其他:
return functools.reduce(list.\uuuu add\uuuuu,reversed(res),[]))
@类方法
def大小(cls):
返回大小(cls)
@类方法
来自结构二进制文件的定义(cls,路径,最大计数=2**32,解码=True):
打印(os.path.getsize(path),cls.size())
断言os.path.getsize(路径)%cls.size()==0
size=os.path.getsize(path)//cls.size()
尺寸=最小值(尺寸,最大计数)
索引=范围(大小)
array=np.fromfile(路径,dtype=cls.dtype(),count=size)
df=pd.DataFrame(数组,index=index)
对于attr,评估中的tp(str(cls.DType()):
如果re.match('S\d+',tp)不是None并解码:
尝试:
df[attr]=df[attr].map(lambda x:x.decode(“utf-8”))
除:
df[attr]=df[attr].map(lambda x:x.decode(“gbk”))
返回df
类StructBase(_StructBase):
_字段=[
(“类型”,ctypes.c_uint32),
]
类索引结构(StructBase):
_字段=[
('Seq',ctypes.c_uint32),
('ExID',ctypes.c_char*8),
(“SecID”,ctypes.c_char*8),
(“SecName”,ctypes.c_char*16),
('SourceID',ctypes.c_int32),
(“时间”,ctypes.c_uint32),
('PreClose',ctypes.c_uint32),
(“开放”,ctypes.c_uint32),
(“高”,ctypes.c_uint32),
(“低”,ctypes.c_uint32),
(“匹配”,ctypes.c_uint32),
]
df=IndexStruct.from_struct_binary('您的路径')
打印(df)

-1:请修复缩进并解释此代码演示的内容。这似乎不适用于大于结构大小的数据。我的二进制数据会自动重复。@lejon:它不会从中删除读取的数据
import struct

struct_fmt = '=5if255s' # int[5], float, byte[255]
struct_len = struct.calcsize(struct_fmt)
struct_unpack = struct.Struct(struct_fmt).unpack_from

results = []
with open(filename, "rb") as f:
    while True:
        data = f.read(struct_len)
        if not data: break
        s = struct_unpack(data)
        results.append(s)
def read_chunks(f, length):
    while True:
        data = f.read(length)
        if not data: break
        yield data

with open(filename, "rb") as f:
    results = [struct_unpack(chunk) for chunk in read_chunks(f, struct_len)]
from functools import partial

with open(filename, "rb") as f:
    results = [struct_unpack(chunk) for chunk in iter(partial(f.read, struct_len), b'')]