Ich versuche eine BMP- Datei in Python zu lesen . Ich weiß, dass die ersten beiden Bytes die BMP-Firma angeben. Die nächsten 4 Bytes sind die Dateigröße. Wenn ich ausführe:
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 anscheinend als Zeichen und gibt eine Zeichenfolge zurück, die nicht in eine Ganzzahl konvertiert werden kann. Wie kann ich das richtig machen?
Antworten:
Die
read
Methode gibt eine Folge von Bytes als Zeichenfolge zurück. Verwenden Sie das integriertestruct
Modul http://docs.python.org/library/struct.html, um von einer Zeichenfolgenbyte-Sequenz in Binärdaten zu konvertieren .import struct print(struct.unpack('i', fin.read(4)))
Beachten Sie, dass
unpack
immer ein Tupel zurückgegeben wird, alsostruct.unpack('i', fin.read(4))[0]
der ganzzahlige Wert, nach dem Sie suchen.Sie sollten wahrscheinlich die Formatzeichenfolge verwenden
'<i'
(<ist ein Modifikator, der die Little-Endian-Bytereihenfolge sowie die Standardgröße und -ausrichtung angibt - standardmäßig wird die Bytereihenfolge, -größe und -ausrichtung der Plattform verwendet). Gemäß der BMP-Formatspezifikation sollten die Bytes in Intel / Little-Endian-Bytereihenfolge geschrieben werden.quelle
i = struct.unpack(...)[0]
ich ofti, = struct.unpack(...)
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' stellt den Datentyp dar 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 viel schneller sind als die Verwendung von Python-Listen.
quelle
a = np.fromfile('file.bin', dtype=np.uint32)
Ab Python 3.2+ können Sie dies auch mit der
from_bytes
nativen int-Methode erreichen:file_size = int.from_bytes(fin.read(2), byteorder='big')
Beachten Sie, dass Sie für diese Funktion angeben müssen, ob die Nummer im Big- oder Little-Endian-Format codiert ist. Daher müssen Sie die Endianität bestimmen, um sicherzustellen, dass sie ordnungsgemäß funktioniert.
quelle
Außer
struct
Sie können aucharray
Modul verwendenimport array values = array.array('l') # array of long integers values.read(fin, 1) # read 1 integer file_size = values[0]
quelle
array
ist eine effiziente Methode zum Lesen einer Binärdatei, aber nicht sehr flexibel, wenn wir uns mit Struktur befassen müssen, wie Sie richtig erwähnt haben.Während Sie die Binärdatei lesen, müssen Sie sie in eine Ganzzahl entpacken. Verwenden Sie dazu das Strukturmodul
import struct fin = open("hi.bmp", "rb") firm = fin.read(2) file_size, = struct.unpack("i",fin.read(4))
quelle
Wenn Sie aus einer Binärdatei lesen, wird ein Datentyp namens Bytes verwendet. Dies ist ein bisschen wie Liste oder Tupel, außer dass nur ganze Zahlen von 0 bis 255 gespeichert werden können.
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))
quelle