前段時間使用python解析idx檔案格式的mnist資料集,需要對二進位制檔案進行讀取操作,其中我使用的是struct模組。查了網上挺多教程都寫的挺好的,不過對新手不是很友好,所以我重新整理了一些筆記以供快速上手。
注:教程中以下四個名詞同義:二進位製流、二進位制陣列、位元組流、位元組陣列在struct模組中,將乙個整型數字、浮點型數字或字元流(字元陣列)轉換為位元組流(位元組陣列)時,需要使用格式化字串fmt告訴struct模組被轉換的物件是什麼型別,比如整型數字是'i',浮點型數字是'f',乙個ascii碼字元是's'。
def demo1():
# 使用bin_buf = struct.pack(fmt, buf)將buf為二進位制陣列bin_buf
# 使用buf = struct.unpack(fmt, bin_buf)將bin_buf二進位制陣列反轉換回buf
# 整型數 -> 二進位製流
buf1 = 256
bin_buf1 = struct.pack('i', buf1) # 'i'代表'integer'
ret1 = struct.unpack('i', bin_buf1)
print bin_buf1, ' <====> ', ret1
# 浮點數 -> 二進位製流
buf2 = 3.1415
bin_buf2 = struct.pack('d', buf2) # 'd'代表'double'
ret2 = struct.unpack('d', bin_buf2)
print bin_buf2, ' <====> ', ret2
# 字串 -> 二進位製流
buf3 = 'hello world'
bin_buf3 = struct.pack('11s', buf3) # '11s'代表長度為11的'string'字元陣列
ret3 = struct.unpack('11s', bin_buf3)
print bin_buf3, ' <====> ', ret3
# 結構體 -> 二進位製流
# 假設有乙個結構體
# struct header
bin_buf_all = struct.pack('id11s', buf1, buf2, buf3)
ret_all = struct.unpack('id11s', bin_buf_all)
print bin_buf_all, ' <====> ', ret_all
輸出結果如下:
demo1輸出結果
struct模組中最重要的三個函式是pack(), unpack(), calcsize()
# 按照給定的格式化字串,把資料封裝成字串(實際上是類似於c結構體的位元組流)
string = struct.pack(fmt, v1, v2, ...)
# 按照給定的格式(fmt)解析位元組流string,返回解析出來的tuple
tuple = unpack(fmt, string)
# 計算給定的格式(fmt)占用多少位元組的記憶體
offset = calcsize(fmt)
struct中支援的格式如下表:
format
c type
python
位元組數x
pad byte
no value1c
char
string of length 11b
signed char
integer1b
unsigned char
integer1?
_bool
bool1h
short
integer2h
unsigned short
integer2i
intinteger4i
unsigned int
integer or lon4l
long
integer4l
unsigned long
long4q
long long
long8q
unsigned long long
long8f
float
float4d
double
float8s
char
string1p
char
string1p
void *
long
注1:q和q只在機器支援64位操作時有意思為了同c中的結構體交換資料,還要考慮有的c或c++編譯器使用了位元組對齊,通常是以4個位元組為單位的32位系統,故而struct根據本地機器位元組順序轉換.可以用格式中的第乙個字元來改變對齊方式.定義如下:注2:每個格式前可以有乙個數字,表示個數
注3:s格式表示一定長度的字串,4s表示長度為4的字串,但是p表示的是pascal字串
注4:p用來轉換乙個指標,其長度和機器字長相關
注5:最後乙個可以用來表示指標型別的,佔4個位元組
character
byte order
size and alignment
@native
native 湊夠4個位元組
=native
standard 按原位元組數
<
little-endian
standard 按原位元組數
>
big-endian
standard 按原位元組數
!network (= big-endian)
standard 按原位元組數
使用方法是放在fmt的第乙個位置,就像'@5s6sif'
Python 位元組流寫入檔案
用struct模組 三個函式 pack unpack calcsize 按照給定的格式 fmt 把資料封裝成字串 實際上是類似於c結構體的位元組流 pack fmt,v1,v2,按照給定的格式 fmt 解析位元組流string,返回解析出來的tuple unpack fmt,string 計算給定的...
網路位元組流和主機位元組流
位元組流分為兩類 little edition le big edition be 0x123456 在兩種位元組流中的儲存方式 位址 le be 0x0000 56 12 0x0001 34 34 0x0002 12 56 主機位元組流根據cpu型別而定 網路位元組流採用be格式 為了進行轉換 b...
位元組流應用
位元組流的一些用法 將位元組流檔案放入乙個緩衝區直接讀出 public static void readfile3 throws ioexception 將位元組檔案讀取到位元組緩衝區 public static void readfile2 throws ioexception fis.close...