ホームページ  >  記事  >  バックエンド開発  >  Pythonでバイナリデータを読み取るにはどうすればよいですか?

Pythonでバイナリデータを読み取るにはどうすればよいですか?

PHPz
PHPz転載
2023-05-08 18:58:062049ブラウズ

bytes

bytes: 文字シーケンスの一種。 dir(str) と dir(bytes) を比較すると、この 2 つのプロパティとメソッドは非常によく似ていますが、相違点はわずかであることがわかります。したがって、バイトも文字列と同様にバイト列に対して検索(find)、長さ(len)、切り取り(分割)、スライスなどのさまざまな操作方法を行うことができます。

バイトの利点は、それが Python の組み込みメソッドであり、追加のサードパーティ モジュールをインストールする必要がないことです。

しかし、欠点も明らかです。クエリできるのは 1 つのクエリのみであり、必要な複数の結果を一度にクエリすることはできません。

まず、オープンの rb モードでファイルを開き、内容をバイト型として読み取ります。特定の文字列を検索する find() メソッドがありますが、このメソッドは要件を満たす最初の文字列インデックスのみを見つけることができ、単一ビットのインデックスではなく、8 ビットの半バイトのインデックスを提供します。複数の一致する文字列を検索する必要がある場合、組み込みの findall() メソッドはありません。複数のクエリを実行する場合は、最初に一致するインデックス 1 を検索し、このインデックス 1 から開始し、2 番目に一致するインデックス 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 が複数回出現しますが、その回数は必ずしも同じではありません。2 つのインデックス間の内容を取得する必要がありますが、ループしたり、ループしたりすることはできません。一気にチェックしました。キーワード インデックスを取得するには、コメント化されたコード行を複数回実行する必要があります。ファイルデータに開始フラグがいくつあるかわからないので、何回実行されるかわかりませんが、ループすれば解決するはずですが、ループするための変数がないようです。これにより、問題がさらに複雑になります。

第二に、2 つの符号の間の内容を取得するため、上記の処理を 2 回実行する必要があります。したがって、プロセスはさらに複雑になります。

したがって、新しい方法を見つけることが絶対に必要です。

bitstring

bitstring は、バイト ストリームの形式でバイナリ ファイルを読み取るサードパーティ パッケージです。

bitstring.py ファイルの最初の文は次のとおりです: このパッケージは、データのビット単位の作成、操作、および解釈を簡素化するクラスを定義します。

翻訳は次のとおりです: このパッケージはクラスを定義しますデータのビット単位の作成、操作、解釈を簡素化する データのビット単位の作成、操作、解釈。

単純に理解すると、バイト型データを直接操作することになります。

次の 4 つの主要なカテゴリがあります。

Bits -- バイナリ データ用の不変コンテナ。
BitArray -- バイナリ データ用の変更可能なコンテナ。
ConstBitStream -- ストリーミング メソッドを備えた不変コンテナ。
BitStream -- ストリーミング メソッドを備えた可変コンテナ。

Bits -- バイナリ データの不変コンテナ。
BitArray -- バイナリ データの変更可能なコンテナ。
ConstBitStream -- ストリーム メソッドを備えた不変コンテナ。
BitStream -- ストリーム メソッドを備えた可変コンテナ。

バイトと同様に、最初にファイルの内容を読み取り、キーワードのインデックスを見つけて、スライスしてデータの内容を取得します。

# 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)

コード分析では、まず 2 つの必要なクラス ConstBitStream、BitStream をインポートします。ファイルの内容を取得するために、 findall() は一致するすべての文字列インデックスを検索し、 find() は最初に一致する文字列インデックスを検索します。 startとendの2つのリストの小さい方の値をスライスしてデータを取得します 型は「bitstring.ConstBitStream」 BitStream.tobytes()メソッドでbytes型に変換します 漢字は文字化けするので、 decode() を使用してデコードし、必要な文字列を取得します。

プロセス全体は依然として簡潔かつ継続的です。コードでは、findall()、find()、および tobytes() メソッドが使用されます。さらに、注意を払う必要がある細かい詳細が多数あります。たとえば、start_indexs が空の場合は後続のコードを実行すべきではなく、end_indexs が空の場合も同様です。

bitstring パッケージは比較的使いやすいことがわかります。ニーズに応じて使用される方法は比較的少ないですが、実際には他にも多くの方法がありますので、必要に応じて選択してください。

以上がPythonでバイナリデータを読み取るにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。