Python verwendet struct, um Binärdateien zu verarbeiten (Verwendung beim Packen und Entpacken).

高洛峰
Freigeben: 2018-05-14 14:54:24
Original
1687 Leute haben es durchsucht

Manchmal müssen Sie Python verwenden, um Binärdaten zu verarbeiten, z. B. beim Zugriff auf Dateien und Socket-Vorgänge. Zu diesem Zeitpunkt können Sie das Strukturmodul von Python verwenden, um Strukturen in der C-Sprache zu verarbeiten 🎜>

Die drei wichtigsten Funktionen im Strukturmodul sind pack(), unpack(), calcsize()

pack(fmt, v1, v2, ...) entsprechend dem angegebenen Format ( fmt), kapseln Sie die Daten in eine Zeichenfolge (eigentlich einen Byte-Stream ähnlich einer C-Struktur)

unpack(fmt, string) Analysieren Sie die Byte-Stream-Zeichenfolge gemäß dem angegebenen Format (fmt) und geben Sie das analysierte Ergebnis zurück tuple

calcsize(fmt) berechnet, wie viele Bytes Speicher das angegebene Format (fmt) belegt. Die in der

Struktur unterstützten Formate sind wie folgt:

Format C Type Python Anzahl der Bytes

x Füllbyte kein Wert 1

c Zeichenzeichenfolge der Länge 1 1

b vorzeichenbehaftete Zeichenzahl Ganzzahl 1

B vorzeichenlose Zeichenzahl Ganzzahl 1

? _Bool bool 1

h kurze Ganzzahl 2

H vorzeichenlose kurze Ganzzahl 2

i int Ganzzahl 4

I ohne Vorzeichen int integer oder long 4

l long integer 4

L unsigned long long 4

q long long long 8

Q unsigned long long long 8

f float float 4

d double float 8

s char[] string 1

p char[] string 1

P void * long

Hinweis 1. q und Q sind nur interessant, wenn die Maschine den 64-Bit-Betrieb unterstützt

Hinweis 2. Vor jedem Format kann eine Zahl stehen, um die Zahl anzugeben

Hinweis 3. Das s-Format stellt eine Zeichenfolge mit einer bestimmten Länge dar, 4s stellt eine Zeichenfolge mit der Länge 4 dar, aber p stellt eine Pascal-Zeichenfolge dar.

Hinweis 4.P wird zum Konvertieren eines Zeigers in die Länge verwendet davon ist gleich dem Maschinenwort Lange Korrelation

Hinweis 5. Der letzte kann zur Darstellung von Zeigertypen verwendet werden, die 4 Bytes belegen

Um Daten mit der Struktur in c auszutauschen, Einige c oder c müssen ebenfalls berücksichtigt werden. Der Compiler verwendet die Byte-Ausrichtung, normalerweise in Einheiten von 4 Bytes für 32-Bit-Systeme, sodass die Struktur gemäß der Byte-Reihenfolge der lokalen Maschine konvertiert wird. Die Ausrichtung kann mithilfe des ersten Zeichens in geändert werden Format. Es ist wie folgt definiert:

Reihenfolge der Zeichenbytes Größe und Ausrichtung

@ native native Ausreichend 4 Bytes

= nativer Standard Entsprechend der ursprünglichen Anzahl von Bytes

< Little-Endian-Standard

> Big-Endian-Standard-Netzwerk (= Big-Endian)

Standard-Standardbytes

wird an der ersten Position von fmt verwendet, wie „@5s6sif“

Beispiel 1:

Die Struktur ist wie folgt:

Das Obige Strukturdaten werden über socket.recv empfangen und im String s gespeichert. Jetzt können Sie die Funktion unpack() verwenden:

struct Header
{
    unsigned short id;
    char[4] tag;
    unsigned int version;
    unsigned int count;
}
Nach dem Login kopieren

Im obigen Format string ,! zeigt an, dass wir zum Parsen die Netzwerk-Byte-Reihenfolge verwenden müssen, da unsere Daten vom Netzwerk empfangen werden und bei der Übertragung im Netzwerk in der Netzwerk-Byte-Reihenfolge vorliegen. Das folgende H steht für eine vorzeichenlose Kurz-ID und 4s steht für A 4-. Byte lange Zeichenfolge, 2I bedeutet, dass es zwei vorzeichenlose int-Daten gibt.

import struct
id, tag, version, count = struct.unpack("!H4s2I", s)
Nach dem Login kopieren
Durch ein Entpacken wurden unsere Informationen jetzt in ID, Tag, Version, Anzahl gespeichert Lokale Daten einfach in das Strukturformat packen:

Die Pack-Funktion konvertiert ID, Tag, Version und Anzahl in Struktur. Header ist jetzt ein String (eigentlich ein Byte-Stream ähnlich einem c Struktur) und diese Zeichenfolge kann über socket.send(ss) gesendet werden.

Beispiel 2:

ss = struct.pack("!H4s2I", id, tag, version, count);
Nach dem Login kopieren

Zu diesem Zeitpunkt handelt es sich bei Bytes um eine Zeichenfolge, und die Zeichenfolge entspricht dem binären Speicherinhalt von a in Bytes.

Führen Sie dann den umgekehrten Vorgang aus und konvertieren Sie die vorhandenen Binärdatenbytes (eigentlich eine Zeichenfolge) in den Python-Datentyp:

import struct
a=12.34
#将a变为二进制
bytes=struct.pack(&#39;i&#39;,a)
Nach dem Login kopieren
#Beachten Sie, dass das Entpacken ein Tupel zurückgibt!

a,=struct.unpack(&#39;i&#39;,bytes)
Nach dem Login kopieren
Wenn es aus mehreren Daten besteht, kann es so aussehen:

Die Bytes sind zu diesem Zeitpunkt in binärer Form. Die Daten kann direkt in eine Datei wie binfile.write(bytes)

geschrieben werden. Wenn wir es dann brauchen, können wir es auslesen, bytes=binfile.read()

a=&#39;hello&#39;
b=&#39;world!&#39;
c=2
d=45.123
bytes=struct.pack(&#39;5s6sif&#39;,a,b,c,d)
Nach dem Login kopieren
und dann pass struct.unpack() wird in eine Python-Variable dekodiert:

'5s6sif' heißt fmt, was eine formatierte Zeichenfolge ist, die aus Zahlen und Zeichen besteht, 2i bedeutet 2 ganze Zahlen usw. Im Folgenden sind die verfügbaren Zeichen und Typen aufgeführt. ctype bedeutet, dass sie den Typen in Python eins zu eins entsprechen können.

Hinweis: Bei der Verarbeitung von Binärdateien sind Probleme aufgetreten

a,b,c,d=struct.unpack(&#39;5s6sif&#39;,bytes)
Nach dem Login kopieren
Wenn wir Binärdateien verarbeiten, müssen wir die folgende Methode verwenden:

Dann binfile=open( Was ist der Unterschied zwischen den Ergebnissen von Dateipfad,'r')?

Es gibt zwei Unterschiede:

Erstens: Wenn Sie bei der Verwendung von „r“ auf „0x1A“ stoßen, wird dies als das Ende der Datei betrachtet, also EOF. Bei Verwendung von „rb“ tritt dieses Problem nicht auf. Das heißt, wenn Sie im Binärformat schreiben und im Text auslesen, wird nur ein Teil der Datei ausgelesen, wenn „0X1A“ vorhanden ist. Bei Verwendung von „rb“ wird bis zum Ende der Datei gelesen.

Zweitens können wir für die Zeichenfolge x=’abcndef’ len(x) verwenden, um ihre Länge auf 7 zu bringen. Wir nennen n das Zeilenumbruchzeichen, das eigentlich „0X0A“ ist. Wenn wir im Textmodus „w“ schreiben, wird „0X0A“ auf der Windows-Plattform automatisch in zwei Zeichen „0X0D“, „0X0A“ geändert, dh die Dateilänge beträgt tatsächlich 8. Beim Lesen im Textmodus „r“ wird es automatisch in das ursprüngliche Zeilenumbruchzeichen konvertiert. Wenn Sie zum Schreiben in den Binärmodus „wb“ wechseln, bleibt ein Zeichen unverändert und wird beim Lesen so gelesen, wie es ist. Wenn Sie also im Textmodus schreiben und im Binärmodus lesen, müssen Sie dieses zusätzliche Byte berücksichtigen. „0X0D“ wird auch Wagenrücklaufzeichen genannt. Unter Linux wird sich das nicht ändern. Weil Linux nur „0X0A“ zur Darstellung von Zeilenumbrüchen verwendet.

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!