it-swarm.com.de

Eine Binärdatei mit Python lesen

Ich finde es besonders schwierig, Binärdateien mit Python zu lesen. Können Sie mir eine Hand geben? Ich muss diese Datei lesen, die in Fortran 90 leicht zu lesen ist

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)

Im Detail ist das Dateiformat:

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. 

Wie kann ich das mit Python lesen? Ich habe alles versucht, aber es hat nie funktioniert. Gibt es eine Möglichkeit, dass ich ein f90-Programm in Python verwende, diese Binärdatei liest und dann die Daten speichere, die ich verwenden muss?

70
Brian

Lesen Sie den Inhalt der Binärdatei folgendermaßen:

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

dann "entpacken" Sie binäre Daten mit struct.unpack :

Die Startbytes: struct.unpack("iiiii", fileContent[:20])

Der Körper: ignoriert die Kopfbytes und das nachfolgende Byte (= 24); Der verbleibende Teil bildet den Hauptteil, um die Anzahl der Bytes im Hauptteil zu ermitteln, die eine Ganzzahl durch 4 teilen; Der erhaltene Quotient wird mit der Zeichenfolge 'i' multipliziert, um das korrekte Format für die Entpackungsmethode zu erstellen:

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

Das Endbyte: struct.unpack("i", fileContent[-4:])

98
gecco

Im Allgemeinen würde ich empfehlen, dass Sie sich das Python's struct - Modul ansehen. Dies ist bei Python Standard, und es sollte leicht sein, die Spezifikation Ihrer Frage in eine für struct.unpack() geeignete Formatierungszeichenfolge zu übersetzen.

Beachten Sie, dass, wenn zwischen/um die Felder ein "unsichtbarer" Abstand eingefügt wird, Sie dies herausfinden und in den Aufruf von unpack() aufnehmen müssen, sonst lesen Sie die falschen Bits.

Den Inhalt der Datei zu lesen, um etwas auszupacken, ist ziemlich trivial:

import struct

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

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

Dadurch werden die ersten beiden Felder ausgepackt, vorausgesetzt, sie beginnen ganz am Anfang der Datei (keine Auffüllung oder fremde Daten) und nehmen auch die native Byte-Reihenfolge (das @-Symbol) an. Die Variable Is im Formatierungsstring bedeutet "Ganzzahl ohne Vorzeichen, 32 Bit".

22
unwind

Sie könnten numpy.fromfile verwenden, um Daten aus Text- und Binärdateien zu lesen. Sie würden zuerst mit numpy.dtype einen Datentyp erstellen, der Ihr Dateiformat darstellt, und dann diesen Typ mit numpy.fromfile aus der Datei lesen.

10
Chris

So lesen Sie eine Binärdatei in ein bytes-Objekt:

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

So erstellen Sie eine int aus den Bytes 0-3 der Daten:

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

So entpacken Sie mehrere ints aus den Daten:

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