【发布时间】:2016-04-01 02:13:19
【问题描述】:
我曾使用 C 编写二进制格式的文件。我使用的格式如下:
带有 5 个双精度的标头(共 40 个字节):
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);
然后我对 256^3 个“粒子”执行了一个 for cicle。对于每个粒子,我写了 9 个值:第一个是整数,其他 8 个是双精度值,方式如下:
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
}
其中 gp 只是一个包含我的粒子信息的数据结构。然后,对于 256^3 个粒子中的每一个,我总共使用了 68 个字节:4 个字节用于 int + 8*(8 个字节) 用于双打。
我需要的是阅读这种格式,但在 python 中以便制作一些情节,但我对 python 有点陌生。我已经阅读了一些使用 python 以二进制格式读取文件的答案,但我只能读取我的标题,而不是“正文”或有关粒子的其余信息。我尝试过的如下:
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
确实,我觉得我根本看不懂字符串字符“=”和“
【问题讨论】:
-
struct.unpack_from('='+(Npart**3)*'i8d', body_data_read)有效吗?它应该一次读取所有数据,之后您可以将它们拆分为每 9 个值 -
感谢您的回答。它看起来像工作,我没有同样的错误,但是当我尝试拆分它们时,就像我用
pos_x_us = body_data[1]展示的那样,它只分配一个数字,而不是 pos_x_us 的完整数组。我该怎么做? -
是的,
body_data[1]只会获取列表中第二个位置的值。如果你想要所有的 x 值,你想使用切片:body_data[1::9]。 -
成功了!非常感谢!
标签: python c binaryfiles