Pythonでバイナリファイルを読み込む

1Byteずつ読み込む

list = []
f = open('ファイル名','rb')

// 1byte ずつ読み込む
while True:
    // a
    data = f.read(8192)
        // b
        if data:
            // c
            for b in data:
                list.append(b)
        // d
        else:
            break

ポイント

a. オーバーフローさせない
f.read(8192)で、データから8kb分の読出しを行っている。これは、変数を格納するメモリをオーバーフローさせないためである。ちなみに指定せずに行うと、listに溜まったデータがおかしくなっていた。

b. f.read は前に読みだした続きからファイルを読み出す
最後までファイルを読み出したときに、次に読むデータがなくなるので、ifでデータの有無を確かめている。

c. 読み出したデータを1Byteずつ取り出す
for inは普段、配列を順に走査する場合に用いるが、この時はファイルを読み込んだデータを1Byteずつ取り出す役割をもっている。

d. 処理を終了
最後まで読み込まれたため、処理を終了する

指定バイトずつ読み込む

// ファイルは下記のようなものを想定する
// ひとつのデータの大きさ:2byte
// 形式:16進数 リトルエンディアン

// a
import struct

list = []
f = open('ファイル名','rb')

// 指定バイト数ずつ読み込む
while True:
    // b
    data = f.read(2)
    // c
    if data:
        // d
        d = struct.unpack('<h',data)[0]
        list.append(d)
    else:
        break

ポイント

a. バイナリデータ読み込み専用のライブラリ「struct」を使う
struct の何がおいしいか?
// バイトを文字ではなく、指定した型で読み出せる。
// リトルエンディアン、ビッグエンディアンの指定もできる。
// 手作業でいちいち関数やモジュールを作る必要がない。

b. 読み込むバイト数を指定する
f.read(引数):引数に読み込みたいバイト数を指定することで、データから指定バイト数、読み込む命令となる。

c. データの有無
最後まで読み込まれているかどうかチェックする。

d. 指定の形式でデータを読み込む
struct.unpack('<h',data)[0]
第一引数の'<h'について
'<':リトルエンディアン
'h':short(-32768 ~ +32767の整数を表現)
返ってくる変数はタプル型なので最後に[0]を付与して、タプルの先頭のデータを取り出している。

詳しい使い方:公式ドキュメント

この記事が気に入ったらサポートをしてみませんか?