其中,$format跟perl里的pack格式類似,有如下一些(中文是我加的,有不準(zhǔn)確的歡迎提出):
a NUL-padded string,即“\0”作為“空字符”的表示形式
A SPACE-padded string,空格作為“空字符”的表示形式
h Hex string, low nibble first,升序位順序
H Hex string, high nibble first,降序位順序
c signed char,有符號單字節(jié)
C unsigned char,無符號單字節(jié)
s signed short (always 16 bit, machine byte order)
S unsigned short (always 16 bit, machine byte order)
n unsigned short (always 16 bit, big endian byte order)
v unsigned short (always 16 bit, little endian byte order)
i signed integer (machine dependent size and byte order)
I unsigned integer (machine dependent size and byte order)
l signed long (always 32 bit, machine byte order)
L unsigned long (always 32 bit, machine byte order)
N unsigned long (always 32 bit, big endian byte order)
V unsigned long (always 32 bit, little endian byte order)
f float (machine dependent size and representation)
d double (machine dependent size and representation)
x NUL byte,實際使用的時候作為跳過多少字節(jié)用,很有用
X Back up one byte,后退1字節(jié)
@ NUL-fill to absolute position,實際使用的時候作為從開頭跳到某字節(jié)用,很有用
實際使用發(fā)現(xiàn):C里的“\0”(即字符串終止符)在php里并不是終止符,而是作為了字符串的一部分。因此,必須對“\0”進(jìn)行特殊處理,才能進(jìn)行struct和php內(nèi)部數(shù)據(jù)的完美互轉(zhuǎn)。比如 char name[10]; 如果實際數(shù)據(jù)是“62 69 61 6E 00 62 69 61 6E 00”,在C語言里第5個位置有終止符,name應(yīng)該是“bian”;而用了unpack轉(zhuǎn)換以后在php里的name卻是“bian\0bian\0”。
一開始我用了strpos函數(shù)找到“\0”的位置,然后進(jìn)行substr截?。?/p>
不過很Faint的事情發(fā)生了,不知道是strpos的bug還是substr的bug(其實測試一下就知道,懶得試),有些字符串沒問題,有些字符串卻只能得到空值(即$name == ”)。很是郁悶,后來找了個strtok函數(shù),這下沒有問題了:
難為大家看了那么多,下面寫個完整的php讀取二進(jìn)制數(shù)據(jù)流(C語言結(jié)構(gòu)體struct數(shù)據(jù))文件的示例代碼:
首先是C的struct定義示例,為了演示,我就寫個簡單點的,實際對照上面那個$format格式表應(yīng)該沒有問題:
比如有個“bianbian.org”文件,內(nèi)容就是上面的N個BIANBIAN結(jié)構(gòu)體構(gòu)成的。讀取的php代碼:
pack應(yīng)該跟unpack相反。