web-dev-qa-db-ja.com

pythonを使用したバイナリファイルの読み取り

Pythonでバイナリファイルを読むのは特に難しいと思います。手伝って頂けますか?このファイルを読む必要があります。Fortran90では、

int*4 n_particles, n_groups
real*4 group_id(n_particles)
read (*) n_particles, n_groups
read (*) (group_id(j),j=1,n_particles)

詳細には、ファイル形式は次のとおりです。

Bytes 1-4 -- The integer 8.
Bytes 5-8 -- The number of particles, N.
Bytes 9-12 -- The number of groups.
Bytes 13-16 -- The integer 8.
Bytes 17-20 -- The integer 4*N.
Next many bytes -- The group ID numbers for all the particles.
Last 4 bytes -- The integer 4*N. 

Pythonでこれを読むにはどうすればよいですか?私はすべてを試しましたが、うまくいきませんでした。 Pythonでf90プログラムを使用してこのバイナリファイルを読み取り、使用する必要があるデータを保存する可能性はありますか?

80
Brian

次のようなバイナリファイルの内容を読んでください。

with open(fileName, mode='rb') as file: # b is important -> binary
    fileContent = file.read()

次に、 struct.unpack を使用してバイナリデータを「アンパック」します。

開始バイト:struct.unpack("iiiii", fileContent[:20])

本文:見出しバイトと末尾バイト(= 24)を無視します。残りの部分は本文を形成し、本文のバイト数を知るために4で整数除算を行います。取得した商に文字列'i'を掛けて、unpackメソッドの正しい形式を作成します。

struct.unpack("i" * ((len(fileContent) -24) // 4), fileContent[20:-4])

終了バイト:struct.unpack("i", fileContent[-4:])

116
gecco

一般的には、Pythonの struct モジュールの使用を検討することをお勧めします。 Pythonの標準であり、質問の仕様をstruct.unpack()に適したフォーマット文字列に簡単に変換できるはずです。

フィールド間に/周りに「見えない」パディングがある場合、それを把握してunpack()呼び出しに含めるか、間違ったビットを読み取る必要があることに注意してください。

解凍するためにファイルの内容を読み取ることは非常に簡単です。

import struct

data = open("from_fortran.bin", "rb").read()

(eight, N) = struct.unpack("@II", data)

これは、ファイルの最初から始まる(パディングや無関係なデータがない)ことを前提とし、ネイティブのバイト順(@シンボル)を想定して、最初の2つのフィールドをアンパックします。書式設定文字列のIsは、「符号なし整数、32ビット」を意味します。

24
unwind

numpy.fromfile を使用すると、テキストファイルとバイナリファイルの両方からデータを読み取ることができます。 numpy.dtype を使用してファイル形式を表すデータ型を最初に構築し、numpy.fromfileを使用してこの型をファイルから読み取ります。

12
Chris

バイナリファイルをbytesオブジェクトに読み込むには:

from pathlib import Path
data = Path('/path/to/file').read_bytes()  # Python 3.5+

データのバイト0〜3からintを作成するには:

i = int.from_bytes(data[:4], byteorder='little', signed=False)

データから複数のintsをアンパックするには:

import struct
ints = struct.unpack('iiii', data[:16])
2
Eugene Yarmash