Python 使用struct.unpack读取4个字节

Python 使用struct.unpack读取4个字节,python,struct,Python,Struct,我有一个文件,其字节11-15包含一个4字节长的整数。使用struct.unpack,我想将其读取为4字节整数。现在,将PACK_FORMAT设置为8s2s4B2s16B96s40B40B,我读取了4个单独的字节: PACK_FORMAT = '8s2s4B2s16B96s40B40B' fd = open('./myfile', 'r') hdrBytes = fd.read(208) print(repr(hdrBytes)) foo = struct.unpack(PACK_FORMAT

我有一个文件,其字节11-15包含一个4字节长的整数。使用
struct.unpack
,我想将其读取为4字节整数。现在,将PACK_FORMAT设置为
8s2s4B2s16B96s40B40B
,我读取了4个单独的字节:

PACK_FORMAT = '8s2s4B2s16B96s40B40B'
fd = open('./myfile', 'r')
hdrBytes = fd.read(208)
print(repr(hdrBytes))

foo = struct.unpack(PACK_FORMAT, hdrBytes)

(Pdb) foo[0]
'MAGICSTR'
(Pdb) foo[1]
'01'
(Pdb) foo[2:6]
(48, 50, 48, 48)
(Pdb) print repr(hdrBytes)
'MAGICSTR010200a0000000001e100010........`
现在我可以将这4个字节转换为int,如下所示:

(Pdb) int(''.join([chr(x) for x in foo[2:6]]), 16)
512
当我修改了
PACK_FORMAT
以使用
I
而不是
4B
来读取4个字节时,总是会出现错误:

foo = struct.unpack(PACK_FORMAT, hdrBytes)
error: unpack requires a string argument of length 210

看起来您违反了对齐要求:整数必须位于计算机上的4字节边界上

可以通过以等号开始格式字符串来关闭对齐:


PACK_FORMAT='=8s2si2s16B96s40B40B'

看起来您违反了对齐要求:整数必须位于计算机上的4字节边界上

可以通过以等号开始格式字符串来关闭对齐:


PACK_FORMAT='=8s2si2s16B96s40B40B'

它与对齐有关-请参阅


这与对齐有关-请参阅


格式字符的顺序可能会影响大小,因为满足对齐要求所需的填充不同:>>>pack('ci','',0x12131415')*\x00\x00\x00\x12\x13\x14\x15'>>>pack('ic',0x12131415',)'\x12\x13\x14\x15*>>calcsize('ci')8>>calcsize('ic')5这是手册中的内容。格式字符的顺序可能会影响大小,因为满足对齐要求所需的填充不同:>>>pack('ci','',0x12131415)*\x00\x00\x12\x13\x14\x15'>>pack('ic',0x12131415',)'\x12\x13\x14\x15*'>>calcsize('ci')('8>>calcsize('ic')5这是手册中的正确内容听起来可能是字节顺序问题,请尝试使用
P.S.大多数二进制格式指定其中的数据是大端还是小端格式(或者在标题中的某个位置有一个标志,表明使用的是哪个)。如果
0200
应该表示512位十进制,然后它看起来像是大端格式的值,所以尝试使用
而不是
=
。后者意味着任何你的计算机本机的东西,它显然可以不同于文件中的数据。我发现了问题,0200是一个ASCII字符串,而不是二进制数据
808595504
十进制是二进制的
0x30323030
,如果解释为字符串,则为
“0200”
,因此您需要的是格式字符串中的
4c
,您需要使用
int(foo[2])
手动将其转换为十进制数。欢迎使用。进一步考虑,您的所有数据似乎都是字符串格式,因此您需要相应地修改整个格式字符串(为每个子字符串使用
c
format字符),然后相应地转换表示十进制或十六进制数的数据-
int()
如果指定基数,则可以从字符串转换两种类型的数字。ie
int(foo[2],16)
听起来可能是字节顺序问题,请尝试使用
P.S。大多数二进制格式指定其中的数据是采用大端还是小端格式(或者在标题中某处有一个标志,表明正在使用哪个)。如果
0200
应该表示512位小数,然后它看起来像是大端格式的值,所以尝试使用
而不是
=
。后者意味着任何你的计算机本机的东西,它显然可以不同于文件中的数据。我发现了问题,0200是一个ASCII字符串,而不是二进制数据
808595504
十进制是二进制的
0x30323030
,如果解释为字符串,则为
“0200”
,因此您需要的是格式字符串中的
4c
,您需要使用
int(foo[2])
手动将其转换为十进制数。欢迎使用。进一步考虑,您的所有数据似乎都是字符串格式,因此您需要相应地修改整个格式字符串(为每个子字符串使用
c
format字符),然后相应地转换表示十进制或十六进制数的数据-
int()
如果指定基数,则可以从字符串转换两种类型的数字。ie
int(foo[2],16)
import struct

PACK_FORMAT1 = '8s 2s 4B 2s 16B 96s 40B 40B'
print(struct.Struct(PACK_FORMAT1).size)  # -> 208

PACK_FORMAT2 = '8s 2s i 2s 16B 96s 40B 40B'
print(struct.Struct(PACK_FORMAT2).size)  # -> 210

PACK_FORMAT3 = '=8s 2s i 2s 16B 96s 40B 40B'
print(struct.Struct(PACK_FORMAT3).size)  # -> 208