deflate — Deflate-Komprimierung und -Dekomprimierung¶
Dieses Modul ermöglicht die Komprimierung und Dekomprimierung von Binärdaten mit dem DEFLATE-Algorithmus (häufig verwendet in der zlib-Bibliothek und im gzip-Archivierer). Hinzugefügt in MicroPython v1.21.
Verfügbarkeit auf den von OpenMV unterstützten Boards:
Board |
Dekomprimierung |
Komprimierung |
|---|---|---|
OpenMV Cam N6 |
Ja |
Nein |
OpenMV AE3 |
Ja |
Ja |
OpenMV Cam RT1062 |
Ja |
Ja |
OpenMV Cam Pure Thermal |
Ja |
Nein |
OpenMV Cam M4 |
Ja |
Nein |
OpenMV Cam M7 |
Ja |
Nein |
OpenMV Cam H7 |
Ja |
Nein |
OpenMV Cam H7 Plus |
Ja |
Nein |
Arduino Giga |
Ja |
Nein |
Arduino Portenta H7 |
Ja |
Nein |
Arduino Nicla Vision |
Ja |
Nein |
Arduino Nano 33 BLE Sense |
Ja |
Nein |
Arduino Nano RP2040 Connect |
Ja |
Nein |
Klassen¶
- class deflate.DeflateIO(stream: Any, format: int = AUTO, wbits: int = 0, close: bool = False, /)¶
Diese Klasse kann verwendet werden, um einen stream zu umhüllen, der ein beliebiges stream-like-Objekt wie eine Datei, ein Socket oder ein Stream ist (einschließlich
io.BytesIO). Sie ist selbst ein Stream und implementiert die Standardmethoden read/readinto/write/close.Der stream muss ein blockierender Stream sein. Nicht-blockierende Streams werden derzeit nicht unterstützt.
Das format kann auf eine der unten definierten Konstanten gesetzt werden und ist standardmäßig
AUTO, was beim Dekomprimieren gzip- oder zlib-Streams automatisch erkennt und beim Komprimieren einen Raw-Stream erzeugt.Der Parameter wbits legt den Logarithmus zur Basis 2 der DEFLATE-Wörterbuch-Fenstergröße fest. Setzt man wbits beispielsweise auf
10, beträgt die Fenstergröße 1024 Bytes. Gültige Werte sind5bis einschließlich15(entsprechend Fenstergrößen von 32 bis 32k Bytes).Wird wbits auf
0gesetzt (der Standardwert), so wird bei der Komprimierung eine Fenstergröße von 256 Bytes verwendet (als wäre wbits auf 8 gesetzt). Bei der Dekomprimierung hängt es vom Format ab:RAWverwendet 256 Bytes (entsprechend wbits gleich 8).ZLIB(oderAUTOmit erkanntem zlib) verwendet den Wert aus dem zlib-Header.GZIP(oderAUTOmit erkanntem gzip) verwendet 32 Kilobytes (entsprechend wbits gleich 15).
Weitere Informationen zur Fenstergröße sowie zu zlib- und gzip-Streams finden Sie in den Hinweisen zur Fenstergröße weiter unten.
Wird close auf
Truegesetzt, so wird der zugrunde liegende Stream automatisch geschlossen, sobald derdeflate.DeflateIO-Stream geschlossen wird. Dies ist nützlich, wenn Sie einendeflate.DeflateIO-Stream zurückgeben möchten, der einen anderen Stream umhüllt, ohne dass der Aufrufer die Verwaltung des zugrunde liegenden Streams kennen muss.Wenn die Komprimierung aktiviert ist, unterstützt eine gegebene
deflate.DeflateIO-Instanz sowohl Lesen als auch Schreiben. So kann beispielsweise ein bidirektionaler Stream wie ein Socket umhüllt werden, was eine Komprimierung/Dekomprimierung in beide Richtungen ermöglicht.
Konstanten¶
Die vier format-Konstanten wählen das Framing aus, das um den rohen Deflate-Bitstrom herum angewendet wird.
- deflate.AUTO: int¶
Bei der Dekomprimierung wird das Eingabeformat durch Untersuchen der ersten Bytes des Streams automatisch erkannt (zlib oder gzip). Bei der Komprimierung wird ein roher Deflate-Stream ohne Header oder Trailer erzeugt (entspricht
RAW).
- deflate.RAW: int¶
Ein roher Deflate-Stream (kein Header, kein Trailer, keine Prüfsumme). Da der Stream keine Metadaten enthält, kann der Dekomprimierer die Fenstergröße nicht aus den Daten rekonstruieren, sodass wbits beim Dekomprimieren explizit gesetzt werden sollte – andernfalls könnte das standardmäßige 256-Byte-Fenster zu klein sein.
- deflate.ZLIB: int¶
Ein zlib-umhüllter Deflate-Stream gemäß RFC 1950: ein 2-Byte-Header, der die Fenstergröße aufzeichnet, die Deflate-Nutzlast und eine abschließende Adler-32-Prüfsumme. Kompakt und selbstbeschreibend; gut für den Einsatz in eingebetteten Systemen geeignet.
- deflate.GZIP: int¶
Ein gzip-umhüllter Deflate-Stream gemäß RFC 1952: ein Header mit optionalen Metadaten wie Dateiname/Zeitstempel, die Deflate-Nutzlast und eine abschließende CRC-32-Prüfsumme nebst unkomprimierter Länge. Dies ist das Format, das vom Kommandozeilentool
gzipund vongzip.GzipFileerzeugt wird. Der Header zeichnet die Fenstergröße nicht auf, sodass der Dekomprimierer 32 KiB annehmen muss, sofern wbits nicht gesetzt ist.
Beispiele¶
Ein typischer Anwendungsfall für deflate.DeflateIO ist das Lesen oder Schreiben einer komprimierten Datei aus dem Speicher:
import deflate
# Writing a zlib-compressed stream (uses the default window size of 256 bytes).
with open("data.z", "wb") as f:
with deflate.DeflateIO(f, deflate.ZLIB) as d:
# Use d.write(...) etc
# Reading a zlib-compressed stream (auto-detect window size).
with open("data.z", "rb") as f:
with deflate.DeflateIO(f, deflate.ZLIB) as d:
# Use d.read(), d.readinto(), etc.
Da deflate.DeflateIO ein Stream ist, kann es zum Beispiel mit json.dump() und json.load() verwendet werden (und an allen anderen Stellen, an denen Streams verwendet werden können):
import deflate, json
# Write a dictionary as JSON in gzip format, with a
# small (64 byte) window size.
config = { ... }
with open("config.gz", "wb") as f:
with deflate.DeflateIO(f, deflate.GZIP, 6) as f:
json.dump(config, f)
# Read back that dictionary.
with open("config.gz", "rb") as f:
with deflate.DeflateIO(f, deflate.GZIP, 6) as f:
config = json.load(f)
Falls Ihre Quelldaten nicht im Stream-Format vorliegen, können Sie io.BytesIO verwenden, um sie in einen Stream umzuwandeln, der sich für deflate.DeflateIO eignet:
import deflate, io
# Decompress a bytes/bytearray value.
compressed_data = get_data_z()
with deflate.DeflateIO(io.BytesIO(compressed_data), deflate.ZLIB) as d:
decompressed_data = d.read()
# Compress a bytes/bytearray value.
uncompressed_data = get_data()
stream = io.BytesIO()
with deflate.DeflateIO(stream, deflate.ZLIB) as d:
d.write(uncompressed_data)
compressed_data = stream.getvalue()
Deflate-Fenstergröße¶
Die Fenstergröße begrenzt, wie weit der (De-)Komprimierer im Stream zurückreferenzieren kann. Eine Vergrößerung der Fenstergröße verbessert die Komprimierung, erfordert jedoch mehr Speicher und macht den Komprimierer langsamer.
Wenn ein Eingabestream mit einer bestimmten Fenstergröße komprimiert wurde, schlägt DeflateIO mit einer kleineren Fenstergröße mitten in der Dekomprimierung mit OSError fehl, allerdings nur, wenn eine Rückreferenz tatsächlich weiter zurückverweist als die Fenstergröße des Dekomprimierers. Das bedeutet, dass eine Dekomprimierung mit einer kleineren Fenstergröße durchaus möglich sein kann. Dies wäre beispielsweise trivialerweise der Fall, wenn die ursprünglichen unkomprimierten Daten kürzer als die Fenstergröße sind.
Dekomprimierung¶
Das zlib-Format enthält einen Header, der die zur Komprimierung der Daten verwendete Fenstergröße angibt. Dies gibt die maximale Fenstergröße an, die zum Dekomprimieren dieses Streams erforderlich ist. Wenn dieser Header-Wert kleiner als der angegebene wbits-Wert ist (oder wenn wbits nicht gesetzt ist), wird der Header-Wert verwendet.
Das gzip-Format enthält die Fenstergröße nicht im Header und geht davon aus, dass alle gzip-Komprimierer (z. B. das Dienstprogramm gzip oder CPythons Implementierung von gzip.GzipFile) die maximale Fenstergröße von 32 KiB verwenden. Aus diesem Grund verwendet der Dekomprimierer, falls der Parameter wbits nicht gesetzt ist, eine Fenstergröße von 32 KiB (entsprechend wbits gleich 15). Das bedeutet, dass Sie mindestens so viel RAM verfügbar haben müssen, um einen beliebigen gzip-Stream dekomprimieren zu können. Wenn Sie die Kontrolle über die Quelldaten haben, sollten Sie stattdessen das zlib-Format mit einer kleineren Fenstergröße in Erwägung ziehen.
Das Raw-Format hat keinen Header und enthält daher keinerlei Informationen über die Fenstergröße. Wenn wbits nicht gesetzt ist, wird standardmäßig eine Fenstergröße von 256 Bytes verwendet, die für einen gegebenen Stream möglicherweise nicht ausreichend groß ist. Daher wird empfohlen, wbits bei Verwendung des Raw-Formats stets explizit zu setzen.
Komprimierung¶
Bei der Komprimierung verwendet MicroPython standardmäßig für alle Formate eine Fenstergröße von 256 Bytes. Dies bietet ein angemessenes Maß an Komprimierung bei minimalem Speicherverbrauch und kurzer Komprimierungszeit und erzeugt eine Ausgabe, die mit jedem Dekomprimierer funktioniert.