it-swarm.com.de

Lesen von Ganzzahlen aus einer Binärdatei in Python

Ich versuche eine BMP -Datei in Python zu lesen. Ich kenne die ersten zwei Bytes Gibt die Firma BMP an. Die nächsten 4 Bytes sind die Dateigröße. Wenn ich ausführen:

fin = open("hi.bmp", "rb")
firm = fin.read(2)  
file_size = int(fin.read(4))  

Ich bekomme:

ValueError: ungültiges Literal für int () mit Basis 10: 'F #\x13'

Ich möchte diese vier Bytes als Ganzzahl lesen, aber Python liest sie als Zeichen und gibt einen String zurück, der nicht in eine Ganzzahl konvertiert werden kann. Wie kann ich das richtig machen? 

67
Manuel Aráoz

Die read-Methode gibt eine Folge von Bytes als Zeichenfolge zurück. Verwenden Sie zum Konvertieren von einer String-Byte-Sequenz in Binärdaten das integrierte Modul struct: http://docs.python.org/library/struct.html

import struct

print(struct.unpack('i', fin.read(4)))

Beachten Sie, dass unpack immer ein Tuple zurückgibt. struct.unpack('i', fin.read(4))[0] gibt also den ganzzahligen Wert an, nach dem Sie suchen.

Sie sollten wahrscheinlich die Formatzeichenfolge '<i' verwenden (<ist ein Modifikator, der die Little-Endian-Bytereihenfolge sowie die Standardgröße und -ausrichtung angibt. Standardmäßig werden die Bytereihenfolge, -größe und -ausrichtung der Plattform verwendet). Gemäß der BMP -Formatspezifikation sollten die Bytes in der Intel/Little-Endian-Bytereihenfolge geschrieben werden.

105
codeape

Eine alternative Methode, die 'struct.unpack ()' nicht verwendet, wäre die Verwendung von NumPy :

import numpy as np

f = open("file.bin", "r")
a = np.fromfile(f, dtype=np.uint32)

'dtype' steht für den Datentyp und kann int #, uint #, float #, complex # oder ein benutzerdefinierter Typ sein. Siehe numpy.fromfile .

Persönlich bevorzugen Sie die Verwendung von NumPy für die Arbeit mit Array-/Matrixdaten, da diese wesentlich schneller ist als die Verwendung von Python-Listen.

38
Emanuel Ey

Ab Python 3.2+ können Sie dies auch mit der Methode from_bytes native int durchführen:

file_size = int.from_bytes(fin.read(2), byteorder='big')

Beachten Sie, dass Sie für diese Funktion angeben müssen, ob die Zahl im Big- oder Little-Endian-Format codiert ist. Sie müssen daher den Endian-Wert festlegen, um sicherzustellen, dass sie korrekt funktioniert.

8
CrepeGoat

Außer struct können Sie auch das Modul array verwenden

import array
values = array.array('l') # array of long integers
values.read(fin, 1) # read 1 integer
file_size  = values[0]
6

Wenn Sie die Binärdatei lesen, müssen Sie sie in eine ganze Zahl entpacken. Verwenden Sie dazu das struct-Modul

import struct
fin = open("hi.bmp", "rb")
firm = fin.read(2)  
file_size, = struct.unpack("i",fin.read(4))
4
Anurag Uniyal

Wenn Sie aus einer Binärdatei lesen, wird ein Datentyp namens Bytes verwendet. Dies ist ein bisschen wie liste oder tuple, außer dass es nur ganze Zahlen von 0 bis 255 speichern kann.

Versuchen:

file_size = fin.read(4)
file_size0 = file_size[0]
file_size1 = file_size[1]
file_size2 = file_size[2]
file_size3 = file_size[3]

Oder:

file_size = list(fin.read(4))

Anstatt:

file_size = int(fin.read(4))
0
Super S