[Python] 簡単にバイナリファイルを読み込む方法【初心者向け】

Python
この記事は約5分で読めます。
マジでヤバイ男性
マジでヤバイ男性

仕事でバイナリファイルを読み込む必要が出てきたんだけど、エディタで中身見れないし、読み込ませるプログラムも書けないし、マジでヤバいんだけど。。

お助けモグラ参上
お助けモグラ参上

バイナリファイルの処理は、プログラム初心者がつまづきやすい箇所かと思いますが、理解すればどうという事はありません。ただ1バイトのデータ(0~255)が連綿と並んでいるだけです。

私もプログラミングが不慣れな時代に、上司から独自フォーマットの顧客バイナリファイルを渡されて対応を丸投げされた時は、正直泣きそうになった記憶があります。

現在はググればいくらでも情報が出来てきますが、それでもプログラム初心者がぱっと見で使えそうな記事は少ない印象でした。

本記事は、当時の自分が読んでも理解出来る内容を目標としています。

そもそもバイナリファイルって何? という方は次の記事が参考になるかもです。

本記事に記載のPythonスクリプト動作確認環境

OS : Windows10(64bit版)
Python version : 3.7.3

スポンサーリンク

Pythonで簡単にバイナリファイルを読み込ませる方法

Pythonスクリプトで読み込ませるバイナリファイル

まずは次のPythonスクリプトを実行して、この記事で扱うバイナリファイルを作成してください。

f = open(r"C:\Python_source\02_BinaryFile\SampleBinary.bin","wb")
for i in range(32):
    f.write(i.to_bytes(1,"big"))
f.close()

1行目のファイルのパスは、必要に応じて変更をお願いします。

作成したバイナリファイルをバイナリエディタで確認すると、下記のようになっているかと思います。

”ADDRESS” が “0” で値が”00″のデータが、アドレスが+1されるたびに+1されて、最後の32個目のデータは “1F(10進数で31)” となっています。

では早速、このバイナリファイルをPythonで読み込んでみましょう。

バイナリファイルを読み込むPythonスクリプトと実行結果

f = open(r"C:\Python_source\02_BinaryFile\SampleBinary.bin","rb")  # バイナリファイル読み込み。
tmp = f.read()  # ファイルの中身をread()メソッドで一気に読み込み。
for idx in range(len(tmp)): # ファイルのバイト数をlen()で取り出して、その回数for文で回す、
  print (tmp[idx]) # 1バイトづつデータを出力
実行結果(0から31までの整数が1行毎に出力されます)

0
1
2
<中略>
29
30
31

Pythonスクリプトの解説

1行目
f = open(r”C:\Python_source\02_BinaryFile\SampleBinary.bin”,”rb”)
は、ファイルをバイナリモードで開いているだけです。
バイナリモードって何?という方は、次の記事をご参照ください。

2行目では、ファイルオブジェクトfをread()メソッドでアクセスする事で、ファイル中のバイトデータ全てを変数tmpへ代入しています。

この時 tmpはbytes型の変数となります。変数のデータ型は、変数をtype()関数へ引数として与える事ですぐに確認出来ます

またPythonのインタラクティブモードでtmpの中身を確認すると、1バイト毎にバックスラッシュで区切られたデータを確認する事が出来ます。

>> type(tmp)
<class 'bytes'> # 変数の方はバイト型
>>> tmp
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'

変数9バイト目のデータが “\t”, 10バイト目のデータが “\n” とおかしな値となっていますが、これはASCIIコード表の文字が、表示の都合で見えてしまっているだけです。共に特殊文字で、”\t” はタブを、”\n” は改行を示しています。

>>> tmp[8]
8
>>> tmp[9]
9
>>> tmp[10]
10
>>> type(tmp[10])
<class 'int'>
>>> 

9バイト目と10バイト目のデータをインタラクティブモードでtmp[9]といった感じでダイレクトに確認すると、想定した値が格納されている事、またtype()で確認する事で各バイトデータは、int(整数)型で取り出される事も分かります。

3行目ファイルのバイト数をlen()で取り出して、その回数for文で回しています。len()の戻り値は32なので、idxには0から31までの整数が代入されたものが、4行目で実行される事となります。4行目print(tmp(idx)) はidxの値を変えながら、32回実行される事となります。

Pythonで読み込ませたデータを加工して出力する

途中で確認したように、tmp[idx]で取り出せる値はint型でした。なのでバイナリファイルから読み出した値を、4行目でプラス100してから出力する事も簡単に出来ます。

f = open(r"C:\Python_source\02_BinaryFile\SampleBinary.bin","rb")
tmp = f.read()
for idx in range(len(tmp)):
  add = tmp[idx]+100
  print (add)
出力結果

100
101
102
<中略>
129
130
131

print() で標準出力をするのではなくバイナリファイルとして保存すれば、元ファイルから加工したバイナリファイルを作る事が可能です。バイナリファイルの書き込みは、次回の記事で解説したいと思います。

最後まで読んで頂き、ありがとうございました。

タイトルとURLをコピーしました