Python でバイナリファイルを読み込む
-
Python の
open()
関数でバイナリファイルを読み込む -
Python でバイナリファイルを
pathlib.Path
で読み込む -
Python の
numpy.fromfile()
関数を用いたバイナリファイルの読み込み
プログラムまたは内部プロセッサは、バイナリファイルを解釈します。バイナリファイルの内容はバイトです。バイナリファイルを読み込むと、bytes
型のオブジェクトが返されています。
Python の open()
関数でバイナリファイルを読み込む
Python では、ファイルオブジェクトを作成するために open()
関数を利用して、そのパスを関数に渡し、特定のモード(デフォルトでは読み込みモード)でファイルを開くことができます。バイナリファイルを開く際には、読み込みモード、書き込みモード、追加モードでファイルを開く際に b
パラメータを指定しなければなりません。このチュートリアルでは、バイナリの読み込みモードである rb
を扱います。
以下のコードでは、バイナリファイルを読み込み、そのファイルから文字を出力します。
with open("sample.bin", "rb") as f:
data = f.read()
print(data[2])
出力:
83
個々の文字を出力すると、整数を表示することができます。
Python には struct
というパッケージがあり、多くのメソッドを持っており、ファイルやデータベースなどに格納されたバイナリデータを扱うのに使うことができます。
指定したフォーマットのレイアウトでパックされたデータを読み込むには、struct.unpack()
を使用します。このようなレイアウトは、データのパッキングやアンパッキングの際に用いられるものであり、フォーマット文字を用いて指定します。これらのフォーマット文字とそのサイズを以下に示します。
関数 struct.unpack()
は常にタプルを返すことに注意してください。
import struct
with open("sample.bin", "rb") as f:
data = f.read()
unpack_result = struct.unpack("hhl", data[0:8])
print(unpack_result)
出力:
(1280, 27731, 7037801)
ここで、hhl
は出力を見ればわかるように、データフォーマットのレイアウトとして short, short, long int を指定しています。フォーマットレイアウトのサイズが 8(2+2+4)なので、解凍用のバッファが 8 バイトしかないのはそのためです。
Python でバイナリファイルを pathlib.Path
で読み込む
また、pathlib
ライブラリの Path
クラスの read_bytes()
メソッドを用いてファイルをバイトモードで読み込み、先ほど示したように struct.unpack()
関数を用いてデータを解釈することもできます。
from pathlib import Path
import struct
data = Path("sample.bin").read_bytes()
multiple = struct.unpack("ii", data[:8])
print(multiple)
出力:
(1817380096, 7037801)
Python の numpy.fromfile()
関数を用いたバイナリファイルの読み込み
もう一つの興味深いアプローチが NumPy
モジュールにあります。このモジュールの fromfile()
関数を用いて、dtype()
関数でフォーマットを指定した後にファイルからバイナリデータを読み込むことができます。これは高速な方法であると考えられます。以下のコードはこれを実装する方法を示しています。
import numpy as np
with open("sample.bin") as f:
rectype = np.dtype(np.int32)
bdata = np.fromfile(f, dtype=rectype)
print(bdata)
出力:
[1817380096 7037801]
ここでは、フォーマットの型を整数-32 ビットに指定し、fromfile()
関数を用いてデータを抽出します。
Manav is a IT Professional who has a lot of experience as a core developer in many live projects. He is an avid learner who enjoys learning new things and sharing his findings whenever possible.
LinkedIn