強火で進め

このブログではプログラム関連の記事を中心に書いてます。

バイナリデータの入力処理

次に unpack() 関数の解説をします。

今回はバイナリエディタで見たときに以下のようなデータとなっているファイル(test.dat)の内容を取り込むサンプルを記述します。

01 02 03 04

こちらのファイルから1バイト読み込む場合はこのように書きます。

from struct import *

f = open('test.dat', 'rb')
print unpack('B', f.read(1))
f.close()
(1,)

この書き方だとタプルで返されるので実際のプログラムでは [0] を加えこのように書きます。

from struct import *

f = open('test.dat', 'rb')
print unpack('B', f.read(1))[0]
f.close()
1

同様に2バイトの場合をはこのようになります。

from struct import *

f = open('test.dat', 'rb')
print unpack('<H', f.read(2))[0]
f.close()
513

2バイト読み込むので read() の引数は2に変わります。
unpack()の説明でも出てきたように2バイト以上の場合はエンディアンの指定が必要となります。
今回もリトルエンディアンで処理しますので < を使います。

10進数だと分かりづらいと思うので16進数で表示するように書き換えます。

from struct import *

f = open('test.dat', 'rb')
print '0x%X' % unpack('<H', f.read(2))[0]
f.close()
0x201

このようにリトルエンディアンなので「0x0201」という並びのデータになります。

同様に4バイトの場合は <L と記述します。

from struct import *

f = open('test.dat', 'rb')
print '0x%X' % unpack('<L', f.read(4))[0]
f.close()
0x4030201

トルエンディアンの場合、バイナリエディタでの表示とプログラム内での表示は以下の対応となります。
この点は慣れるまで注意が必要です。

バイナリエディタ プログラム
01 0x01
01 02 0x0201
01 02 03 04 0x04030201