2017-09-13 2 views
0

Ich versuche, eine Struktur aus einer Binärdatei zu entpacken, und ich weiß, dass die ersten 4 Bytes sind eine ganze Zahl (mit Wert 64) und die nächsten 3 * 8 Bytes sind drei Doppel.Python struct entpacken ganze Zahl gefolgt von double

with open('data', mode='rb') as file: 
    fileContent = file.read() 

Dann versuche ich:

print(struct.unpack("i", fileContent[0:4])) 

und diese korrekt druckt die Nummer 64. Allerdings würde Ich mag auch die folgende Doppel lesen Ich habe die Daten in einem Vektor namens filecontent wie folgt gespeichert I modifizieren, um die Erklärung oben

print(struct.unpack("id", fileContent[0:12])) 

(da die 4 Byte ganze Zahl sein soll und die Doppel sollte 8 sein, was insgesamt 12 Bytes ergibt). Allerdings bekomme ich eine Fehlermeldung, dass

struct.error: unpack requires a bytes object of length 16

Auch, wenn ich versuche, die Doppel nur und Nutzung zu lesen:

print(struct.unpack("d", fileContent[4:12]) 

ich nicht den richtigen Wert des Doppel bekommen! Wenn Sie das Schneiden auf [8:16] ändern, erhalten Sie den korrekten Wert. Kann mir bitte jemand das erklären? Ich weiß sicher, dass die ersten 4 Bytes in der Datei eine ganze Zahl sein sollten und die nächsten 8 sollten ein Double sein. Liest read() die Integer irgendwie mit Nullen, oder was ist los?

+0

Ihre Eingabestruktur ist wahrscheinlich aufgefüllt, so dass das 'double' auf 8 Bytes ausgerichtet ist. –

+0

Ich habe eine binäre Dump im Terminal gemacht und die Eingabedatei 'Daten' ist nicht aufgefüllt (Konto für auf einem Little-Endian-Maschine, die ersten vier Bytes sind 01000000 00000000 00000000 00000000) und die folgenden Bytes sind ungleich Null, und ich denke, sie repräsentieren den Float. Gibt es etwas mit der Funktion read(), die die Daten automatisch auffüllt? – JezuzStardust

Antwort

0

Die unpack() wird automatisch Padding für Sie tun. So wird unpack('id', …) die Ganzzahl auf 8 Bytes auffüllen, deshalb erhalten Sie den Fehler "struct.error: entpacken erfordert ein Byte-Objekt der Länge 16".

Es kann leicht wie folgt zu sehen:

>>> pack('id', 42, 42) 
b'*\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\[email protected]' 

Aber die Lösung ist einfach, wie Sie die endianness der Datei kennen, sollten Sie es an, und es durch specifing wird padding deaktiviert werden:

>>> unpadded = pack('>id', 42, 42) 
>>> len(unpadded) 
12 
>>> unpack('>id', unpadded) 
(42, 42.0) 
Verwandte Themen