2010-04-10 71 views
15

Python的说,我需要4个字节为“BH”的格式代码:struct.error:解包需要长度的字符串参数4

struct.error: unpack requires a string argument of length 4 

下面是代码,我的3个字节把我认为需要:(!?)

major, minor = struct.unpack("BH", self.fp.read(3)) 

“B” 无符号字符(1个字节)+ “H” 无符号短(2个字节)= 3个字节

struct.calcsize( “BH”)说4字节。

编辑:该文件是〜800 MB,这是在文件的前几个字节,所以我相当肯定有数据剩下要读。

回答

20

结构模块模仿C结构。处理器需要更多的CPU周期来读取奇数地址上的16位字或不能被4整除的地址上的32位双字,因此结构会添加“填充字节”以使结构成员落在自然边界上。考虑:

struct {     11 
    char a; 
    short b;  ------------ 
    char c;  axbbcxxxdddd 
    int d; 
}; 

该结构将占用12个字节的内存(x是填充字节)。

Python的工作方式类似(见struct文档):

>>> import struct 
>>> struct.pack('BHBL',1,2,3,4) 
'\x01\x00\x02\x00\x03\x00\x00\x00\x04\x00\x00\x00' 
>>> struct.calcsize('BHBL') 
12 

编译器通常具有消除填充的方式。在Python中,任何= <>!将消除填充:

>>> struct.calcsize('=BHBL') 
8 
>>> struct.pack('=BHBL',1,2,3,4) 
'\x01\x02\x00\x03\x04\x00\x00\x00' 

小心让结构句柄填充。在C中,这些结构如下:

struct A {  struct B { 
    short a;   int a; 
    char b;   char b; 
};    }; 

通常分别是4字节和8字节。在结构用于数组的情况下,填充发生在结构的末尾。这使得'a'成员在数组后面的结构的正确边界上保持一致。 Python的结构模块不垫底:

>>> struct.pack('LB',1,2) 
'\x01\x00\x00\x00\x02' 
>>> struct.pack('LBLB',1,2,3,4) 
'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04' 
+1

我想知道的是为什么Python没有将数据打包成这种格式。 “01 01 00”它打包字节0x01,短0x01,但它试图解压它像“01 00 01 00”。无论如何,我解决了我的问题,我总是在我的所有格式代码之前加上'<',以使它们没有填充的小端。谢谢你的解释。 :) – 2010-04-10 17:47:19

+0

有一个类似的问题,'='和'@'没有解决...使用我在Windows上的Mac上做的代码 – jokoon 2011-09-28 23:57:26

+0

@ThomasO你为什么说它将它打包为“01 01 00”?我看到struct.pack('BH',1,2)=='\ x01 \ x00 \ x02 \ x00'。 – aij 2016-07-14 20:19:05

6

默认情况下,在许多平台上,短对齐的偏移量为2的倍数,所以在char之后会添加填充字节。

要禁用此功能,请使用:struct.unpack("=BH", data)。这将使用标准对齐,不添加填充:

>>> struct.calcsize('=BH') 
3 

=字符将使用本地字节顺序。您也可以分别使用<>而不是=强制小端或大端字节排序。

+0

奇怪的是,我看我的十六进制文件,我有数据01 01 00这显示了版本三个字节:一个“大”字节和单'小'短。声明是否为假? (“BH”,pack(“BH”,3,6))==(3,6)感谢您的帮助。 – 2010-04-10 01:23:27

+0

@Thomas:我不确定你在问什么。您发布的表达式将评估为True。 – interjay 2010-04-10 01:26:35

+0

这就是我的想法,而这正是我正在做的。我使用Python打包了一个简单的数据库,包(“BH”,major_ver,minor_ver),然后使用解包(“BH”)进行解包。在同一台电脑上,这是一台Intel C2D x86-64。额外的字节在哪里?我将使用= BH,但怀疑某个字节正在丢失或获得某处。 – 2010-04-10 01:30:58

相关问题