2010-04-10 175 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

相關問題