Ich habe mit C geschrieben eine Datei im Binärformat geschrieben. Das Format ich verwendet habe, ist die folgende:Lese Binärdaten mit Header von C in Python
einen Header mit 5 Doppel (insgesamt 40 Bytes):
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);
Und dann durchgeführt I A für cicle über 256^3 "Teilchen". Für jedes Teilchen schreiben I 9 Werte: die erste ist eine ganze Zahl und die andere 8 Doppel-, auf folgende Weise:
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 Wo nur eine Datenstruktur ist, die Informationen meiner Teilchen enthält. Dann habe ich für jedes der 256^3 Partikel insgesamt 68 Bytes benutzt: 4 Bytes für das int + 8 * (8 Bytes) für die Doubles.
Was ich brauche ist ein solches Format zu lesen, aber in Python, um einige Plots zu machen, aber ich bin ein wenig neu mit Python. Ich habe einige der Antworten gelesen, um Dateien im Binärformat mit Python zu lesen, aber ich konnte nur meine Kopfzeile lesen, nicht den "Körper" oder den Rest der Informationen bezüglich der Partikel. Was ich habe versucht, ist die folgende:
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]
Aber wenn ich meinen Code ausführen, ich diesen Fehler erhalten:
body_data = struct.unpack('<i 8d', body_data_read)
struct.error: unpack requires a string argument of length 68
ich mit der ersten kommentierte Linie versucht:
#body_data = struct.unpack_from('idddddddd', bdata, offset=40)
Aber der Fehler sagt:
struct.error: unpack requires a string argument of length 72
Wenn ich die Linie
body_data = struct.unpack('=i 8d', body_data_read)
oder die Linie
body_data = struct.unpack('<i 8d', body_data_read)
ich den Fehler erhalten verwende ich zuerst zeigte:
struct.error: unpack requires a string argument of length 68
der Tat, ich fühle mich wie ich überhaupt nicht verstehen, die Zeichenketten "=" und "<", weil ich mit ihnen die angenommene Länge erhalte, die ich lesen muss, aber ich kann nicht lesen. Was ich schließlich brauche, ist ein Array namens pos_x_us mit allen Positionen in x, in pos_y_us die Positionen in y, in pos_z_us die Positionen in z und so weiter für die anderen Werte. Ich werde mich bedanken, wenn Sie mir ein paar Ideen oder Erleuchtung darüber geben können, wie ich erreichen kann, was ich brauche.
Ist 'struct.unpack_from ('=' + (Npart ** 3) * 'i8d', body_data_read)' Arbeit? Es sollte alle Daten auf einmal lesen, nach denen Sie sie alle 9 Werte teilen können – Reti43
Danke von Ihrer Antwort. Es sieht aus wie Werke, ich habe nicht den gleichen Fehler, aber wenn ich versuche, sie so zu teilen, wie ich es mit 'pos_x_us = body_data [1] gezeigt habe, gibt es nur eine Zahl, nicht das komplette Array zu pos_x_us. Wie kann ich es tun? – Darivadi
Ja, 'body_data [1]' holt nur den Wert an der zweiten Position in der Liste. Wenn Sie alle x Werte haben möchten, verwenden Sie Slicing: 'body_data [1 :: 9]'. – Reti43