私はC言語でバイナリ形式でファイルを書きました。私が使用しているフォーマットは以下の通りである:5倍(40バイトの合計)とバイナリデータをCのヘッダでPythonで読む
ヘッダ:
fwrite(&FirstNum, sizeof(double), 1, outFile);
fwrite(&SecNum, sizeof(double), 1, outFile);
fwrite(&ThirdNum, sizeof(double), 1, outFile);
fwrite(&FourthNum, sizeof(double), 1, outFile);
fwrite(&FifthNum, sizeof(double), 1, outFile);
そしてIは、256^3 "粒子" 上cicleに対して行います。各粒子についてI 9つの値を書き込む:最初のものは整数であり、他方8は、以下のように、倍精度である:GPは私の粒子の情報を含むだけのデータ構造である
Ntot = 256*256*256
for(i=0; i<Ntot; i++)
{
fwrite(&gp[i].GID, sizeof(int), 1, outFile);
/*----- Positions -----*/
pos_aux[X] = gp[i].pos[X];
pos_aux[Y] = gp[i].pos[Y];
pos_aux[Z] = gp[i].pos[Z];
fwrite(&pos_aux[0], sizeof(double), 3, outFile); //Positions in 3D
fwrite(&gp[i].DenConCell, sizeof(double), 1, outFile); //Density
fwrite(&gp[i].poten_r[0], sizeof(double), 1, outFile); //Field 1
fwrite(&gp[i].potDot_r[0], sizeof(double), 1, outFile); //Field 2
fwrite(&gp[i].potDot_app1[0], sizeof(double), 1, outFile); //Field 3
fwrite(&gp[i].potDot_app2[0], sizeof(double), 1, outFile); //Field 4
}
。次に、256^3パーティクルのそれぞれについて、私は合計68バイトを使用しました:ダブルスのint + 8 *(8バイト)のために4バイト。
私が必要とするのは、そのような形式を読むのですが、いくつかのプロットを作るためには、Pythonで読むのですが、私は少しPythonを使っています。私はPythonでバイナリ形式のファイルを読む答えをいくつか読んだが、私は自分のヘッダを読むことができただけで、 "body"やその他の粒子に関する情報は読み取れなかった。私がしようとしたことは、次のとおりです。
Npart = 256
with open("./path/to/my/binary/file.bin", 'rb') as bdata:
header_size = 40 # in bytes
bheader = bdata.read(40)
header_data = struct.unpack('ddddd', bheader)
FirstNum = header_data[0]
SecNum = header_data[1]
ThirdNum = header_data[2]
FourthNum = header_data[3]
FifthNum = header_data[4]
#Until here, if I print each number, I obtain the correct values.
#From here, is what I've tried in order to read the 9 data of the
#particles
bytes_per_part = 68
body_size = int((Npart**3) * bytes_per_part)
body_data_read = bdata.read(body_size)
#body_data = struct.unpack_from('idddddddd', bdata, offset=40)
#body_data = struct.unpack('=i 8d', body_data_read)
body_data = struct.unpack('<i 8d', body_data_read)
#+++++ Unpacking data ++++++
ID_us = body_data[0]
pos_x_us = body_data[1]
pos_y_us = body_data[2]
pos_z_us = body_data[3]
DenCon_us = body_data[4]
しかし、私は自分のコードを実行すると、私はこのエラーを取得:
body_data = struct.unpack('<i 8d', body_data_read)
struct.error: unpack requires a string argument of length 68
私が最初のコメント行で試してみました:
#body_data = struct.unpack_from('idddddddd', bdata, offset=40)
しかし、エラーは言う:
struct.error: unpack requires a string argument of length 72
私は私が最初に示したエラー得るラインに
body_data = struct.unpack('=i 8d', body_data_read)
またはライン
body_data = struct.unpack('<i 8d', body_data_read)
を使用する場合:
struct.error: unpack requires a string argument of length 68
を実際に私は全く理解していないように、私は感じます文字列の文字「=」と「<」です。なぜなら、それらの文字を読み込む必要があると思われる長さを得るためですが、私は読むことができません。私が最終的に必要とするのは、pos_y_usにはpos_x_us、pos_y_usにはpos_x_us、posにはpos_z_us、zにはposの位置などがあります。あなたが私に必要なものを得る方法について私にいくつかのアイデアや啓発を与えることができれば感謝します。
'struct.unpack_from( '=' +(Npart ** 3)* 'i8d'、body_data_read)'は動作しますか?一度にすべてのデータを読み込み、その後9つの値ごとに分割することができます – Reti43
ありがとうございます。作品のように見えますが、同じエラーはありませんが、 'pos_x_us = body_data [1] 'で示したように分割しようとすると、完全な配列ではなくpos_x_usに1つの数字だけが割り当てられます。どうしたらいいですか? – Darivadi
うん、 'body_data [1]'はリストの2番目の位置の値だけをフェッチします。すべてのx値が必要な場合は、スライス:body_data [1 :: 9]を使用します。 – Reti43