最近在處理檔案資料需要使用到很多二進為轉換文字的使用,
自己也花一點時間做了一些學習,但看了很多次也找到一些資料,但一周後要開始用,又忘記了(年紀有了)。就想透過網路做一個簡單的學習筆記,也整理一下自己所學的內容。讓自己以後可以有個快速可以回顧。畢竟年紀有了,沒有那麼多記憶空間可以用
Python 下可以有一模組可以讓使用者快速做資料的重新整理,還有格式轉換。通常在一些簡單的單晶片的應用使用的都是二進位資料與文字(ASCII/UTF-8)或者16進位的顯示與轉換。剛好今天我需要用到,而且在python 就已經有這個好用的模組可以使用,完全不需要自己來,節省了很多寫應用程式的時間,非常適合大眾使用。
在 micropythun 下的 struct 模組名稱是 ustruct,u-代表 Micro 的意思。也表示兩者之間有一些差異,差異如下:
ustruct 只提供了以下幾個基本的功能
- calcsize /pack /pack_into / unpack / unpack_from
而struct 提供了更多方便的方法,我覺得比較有用的是 iter_unpack
( format , buffer ),因為它可以使用迭代的方式重複地做完轉換的事情。不過使用基本的unpack 也可以達到相同的效果,只是需要自己組合相關的流程。
因為所使用的是micropython,所以就寫一下這部分的筆記
pack() pack(fmt,v1,v2,…)
- 將變數轉成對應的格式
unpack(fmt,string)
- 將對應的格式轉回數據
calcsize(fmt)
- 計算目前的格式用了多少記憶體
size/byte 的前缀: @
, <
, >
, !
.
byte在記憶體中的排列方式,通常使用在同一個作業系統下是不需要考慮這個問題,但在使用資料的傳輸時候就需要注意雙方的溝通基準。簡單說明如下表格與例子
- @ :依據本機器的特性排列
- < : ARM little endian
- > : Big endian
- ! : 網路資料排列
>>>struct.pack(‘@3b’,255,128,00)
b’\xff\x80\x00'>>>struct.pack(‘@3i’,255,128,00)
b’\xff\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00'>>>struct.pack(‘<3i’,255,128,00)
b’\x00\x00\x00\xff\x00\x00\x00\x80\x00\x00\x00\x00'>>>struct.pack('!3i',255,128,00)
b'\x00\x00\x00\xff\x00\x00\x00\x80\x00\x00\x00\x00'
排>列的使用,需要注意的是在檔案,記憶體,網路傳遞上。
在python 你不確定時可以透過以下的方式來確認機器上面的排列
>>>import sys
>>> sys.byteorder
‘little’
格式: b
, B
, h
, H
, i
, I
, l
, L
, q
, Q
, s
, P
, f
, d
(最後2個需要浮點庫支持)
b : signed char ,1 byte
B : unsigned char ,1 byte
h : short ,2 byte
H : unsigned short ,2 byte
i : int ,4 byte
I : unsigned int ,4 byte
l : long ,4 byte
L : unsigned long ,4 bytel
q : long long ,8 byte
Q : unsigned long long,8 byte
s : char []
P : char []
f : float , 4 byte 使用IEEE 754 binary32
d : double , 8byte 使用IEEE 754 binary64
任務開始
今天我的任務是需要將List 轉換成二進位存放到檔案,然後再讀出轉成List
作法與想法
使用List的作法要注意的是使用*a[]來取得一整個列表
這其中只使用到 'B'這一個格式的轉換
import struct as structa = [[255,0,0],[34,255,0],[4,3,0]]
b=[[]]*3file = open (‘test.bin’,’wb’)
for i in range(3):
w_buffer = struct.pack(‘3B’,*a[i]) #轉換格式到 bytearray
file.write(w_buffer)
file.close()file = open (‘test.bin’,’rb’)
for i in range(3):
r_buffer = file.read(3)
b[i] = struct.unpack(‘3B’,r_buffer)
print (b)
file.close()
執行的結果
[(255, 0, 0), (34, 255, 0), (4, 3, 0)]
你也許會發現轉換出來的資料變成tuple,但不影響到應用。
檔案內容如下截圖