ヘッダーが32バイト、その後に1ビットのデータが4バイト単位で繰り返すバイナリファイルがあります。このファイルを読み込み、1ビット毎のデータを取り出したいと思います。簡単に取り出せるpythonのコードを教えて下さい。

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:2016/11/30 00:57:20
  • 終了:2016/12/06 22:04:21

ベストアンサー

id:TransFreeBSD No.1

TransFreeBSD回答回数667ベストアンサー獲得回数2682016/12/04 22:13:12

openのmodeにはbを加えます。読み込みなら"rb"ですね。
http://docs.python.jp/3.5/library/functions.html#open
バイナリデータの操作にはstructを使います。読み込みはstruct.unpackです。
http://docs.python.jp/3.5/library/struct.html#struct.unpack
フォーマット文字は、ヘッダー32バイトは"32s"、4バイトバイナリは"L"になります。
ただ、ファイルからなら、ヘッダー32バイトはそのままreadで32バイト読めば事足りますし、必要ないならseekがいいでしょう。
固定長毎の読み込みはpartialとiterを使う例が下記にありました。
https://www.safaribooksonline.com/library/view/python-cookbook-3rd/9781449357337/ch05s08.html
http://stackoverflow.com/a/20014805

ってなわけで、外枠はこんな感じでしょうか

from functools import partial
from struct import unpack

DATAFILENAME = 'datafile'
HEADER_SIZE = 32
RECORD_SIZE = 4

with open(DATAFILENAME, 'rb') as f:
    f.seek(HEADER_SIZE)
    for r in iter(partial(f.read, RECORD_SIZE), b''):
        data = unpack('L', r)
        ...

ところで「1ビットのデータが4バイト単位で繰り返す」とは、4バイト単位の繰り返しがあるのは分かるのですが、
・4バイトのうち特定1ビットだけが有効なデータ
・4バイトに1ビット64個のデータがある
のどちらでしょう?

さらに「4バイトのうち特定1ビットだけが有効なデータ」の場合、
・無効な部分はすべて0である
・無効な部分は0とは限らない
のどちらでしょう。
あと、ビットの位置も。
前者なら特に処理する必要なく0かそれ以外かで判断つきますね。
後者なら&(and)とればいいですね。

「4バイトに1ビット64個のデータがある」場合は、並び順があるということでしょうか。
この場合、unpack時にエンディアンを指定したほうが良いかもしれません。
ビット単位にするにはbinがいいかもしれません。

[追記]

bugfixとbitへの分解、一部エラー処理追加しました。

#!/usr/bin/python

from functools import partial
import struct

DATAFILENAME = 'datafile'
HEADER_SIZE = 32
RECORD_SIZE = 4

with open(DATAFILENAME, 'rb') as f:
    f.seek(HEADER_SIZE)
    try:
        for r in iter(partial(f.read, RECORD_SIZE), b''):
            data = struct.unpack('>I', r)[0]
            for bit in map(int, reversed('{:032b}'.format(data))):
                print(bit, end=' ')
            print()
    except struct.error:
        print("last record:", r)
        raise
他1件のコメントを見る
id:TransFreeBSD

4バイトは64ビットじゃなくて32ビットですよね(^^;
なぜか間違えてました。
なので"L"ではなく"I"でした。
ついでにエラー処理も加えました。

4バイト中の1ビットそれぞれを取り出したい

なので1ビット32個に分割しました。
ただ、ピットの並び順が分からないので、ひとまずビッグエンディアンとみなして最下位からとしてます。

2016/12/06 00:10:04
id:taki

ありがとうございます!
このソースで読み込めました。
ポイント無くてすみません。

2016/12/06 22:04:02

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません