首頁 >後端開發 >Python教學 >Python中如何進行二進位資料讀取操作?

Python中如何進行二進位資料讀取操作?

PHPz
PHPz轉載
2023-05-08 18:58:062107瀏覽

bytes

bytes:一種字元序列的型別。透過比較 dir(str) 與 dir(bytes) 可知,兩者的屬性與方法很相似,只有少數幾個不同。所以 bytes 也是可以像 string 一樣,對位元組序列有各種操作方法,如查找(find),求長度(len),切割(split),切片等。

bytes 的優點是:Python 內建的方法,不需要的額外的安裝三方模組。

但缺點也很明顯:只能單一查詢,不能一次查詢多個需要的結果。

首先透過 open 的 rb 模式開啟文件,讀取內容為 bytes 類型。尋找特定字串有 find() 方法,但此方法只能找到第一個符合要求的字串索引,並且給出的不是單位元的索引,而是 8 位元一個位元組的索引。當需要尋找多個符合的字串,卻沒有內建的 findall() 方法。如果要查詢多個,過程會很麻煩,首先查到第一個符合的索引 1,以此索引 1 為開始,查詢第二個符合的索引 2,以此類推,直到查詢結束。

with open(path, 'rb') as f:
    datas = f.read()
    start_char = datas.find(b'Start')
    # start_char2 = datas.find(b'Start', start_char)
    end_char = datas.find(b'End', start_char)
    # end_char2 = datas.find(b'End', start_char2)
    data = datas[start_char:end_char]
    print(data)

注意上述程式碼,start_char 和 end_char 會出現多次,次數並不一定會一樣,需要取得兩個索引之間的內容,但是既無法循環,也不能一次查完。需要多次執行已註解的那行程式碼,取得關鍵字索引。由於不知道檔案資料中會有多少個開始標誌,也就不知道執行多少次,這應該採用循環解決,但似乎沒有可供循環的變數。這使得問題更加複雜。

其次,由於是取得兩個標誌之間的內容,所以,以上過程需要執行兩次。因此過程更顯得繁雜無比。

因此,尋找新的方法,是完全必要的。

bitstring

bitstring 是一個三方包,以位元組流形式讀取二進位檔案。

bitstring.py 檔案的第一句話是:This package defines classes that simplify bit-wise creation, manipulation and interpretation of data.

翻譯如下:這個套件定義的類別簡化了數據的逐位創建、操作和解釋。

簡單理解就是,直接操作 bytes 類型的資料。

有主要的四個類,如下:

Bits -- An immutable container for binary data.
BitArray -- A mutable container for binary data.
ConstBitStream -- An immutable container with streaming methods.
BitStream -- A mutable container with streaming methods.

Bits -- 二進位資料的不可變容器。
BitArray -- 二進位資料的可變容器。
ConstBitStream -- 具有流方法的不可變容器。
BitStream -- 具有流方法的可變容器。

像 bytes 一樣,先讀取檔案內容,尋找關鍵字索引,切片取得資料內容。

# update at 2022/05/06 start
# from bistring import ConstBitStream, BitStream
from bitstring import ConstBitStream, BitStream
# update at 2022/05/06 end

hex_datas = ConstBitStream(filename=path)  # 读取文件内容
start_char = b'Start'
start_chars = hex_datas.findall(start_char, bytealigned=True)  # 一次找到全部符合的,返回一个生成器
start_indexs = []
for start_char in start_chars:
    start_indexs.append(start_char)

end_char = b'End'
end_indexs = []
for start_index in start_indexs:
    end_chars = hex_datas.find(end_char, start=start_index, bytealigned=True)  # 找到第一个符合的,返回元组
    for end_char in end_chars:
        end_indexs.append(end_char)

result = []
for i in range(min(len(start_indexs), len(end_indexs))):
    hex_data = hex_datas[start_indexs[i]:end_indexs[i]]
    str_data = BitStream.tobytes(hex_data).decode('utf-8')
    result.append(str_data)

程式碼分析,首先導入需要的兩個類別:ConstBitStream, BitStream。取得檔案內容,findall() 尋找所有符合的字串索引,find() 尋找第一個符合的字串索引。取開始、結束兩個列表的較小值,切片獲取數據,類型為‘bitstring.ConstBitStream’,BitStream.tobytes() 方法轉為bytes 類型,中文字符會亂碼,所以再用decode() 解碼,得到需要的字串。

整個過程還是簡潔、連續。程式碼中用到了 findall()、find()、tobytes() 方法。另外還有許多小細節要注意,例如,start_indexs 如果為空,後續的程式碼就不該執行了,end_indexs 為空亦是如此。

由此可見,bitstring 這個包還是比較好用的。根據需求,用到的方法比較少,其實還有許多其他的方法,按需選擇。

以上是Python中如何進行二進位資料讀取操作?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除