deflate — compresie și decompresie deflate¶
Acest modul permite compresia și decompresia datelor binare cu algoritmul DEFLATE (folosit frecvent în biblioteca zlib și arhivatorul gzip). Adăugat în MicroPython v1.21.
Disponibilitate pe plăcile acceptate de OpenMV:
Placă |
Decompresie |
Compresie |
|---|---|---|
OpenMV Cam N6 |
Da |
Nu |
OpenMV AE3 |
Da |
Da |
OpenMV Cam RT1062 |
Da |
Da |
OpenMV Cam Pure Thermal |
Da |
Nu |
OpenMV Cam M4 |
Da |
Nu |
OpenMV Cam M7 |
Da |
Nu |
OpenMV Cam H7 |
Da |
Nu |
OpenMV Cam H7 Plus |
Da |
Nu |
Arduino Giga |
Da |
Nu |
Arduino Portenta H7 |
Da |
Nu |
Arduino Nicla Vision |
Da |
Nu |
Arduino Nano 33 BLE Sense |
Da |
Nu |
Arduino Nano RP2040 Connect |
Da |
Nu |
Clase¶
- class deflate.DeflateIO(stream: Any, format: int = AUTO, wbits: int = 0, close: bool = False, /)¶
Această clasă poate fi folosită pentru a încapsula un stream, care este orice obiect asemănător unui flux, cum ar fi un fișier, un socket sau un flux (inclusiv
io.BytesIO). Este la rândul ei un flux și implementează metodele standard read/readinto/write/close.Fluxul stream trebuie să fie un flux blocant. Fluxurile neblocante nu sunt acceptate momentan.
Parametrul format poate fi setat la oricare dintre constantele definite mai jos și implicit are valoarea
AUTO, care la decompresie va detecta automat fluxurile gzip sau zlib, iar la compresie va genera un flux brut.Parametrul wbits setează logaritmul în baza 2 al dimensiunii ferestrei dicționarului DEFLATE. De exemplu, setarea lui wbits la
10setează dimensiunea ferestrei la 1024 de octeți. Valorile valide sunt de la5la15inclusiv (corespunzând unor dimensiuni ale ferestrei de la 32 la 32k octeți).Dacă wbits este setat la
0(valoarea implicită), atunci pentru compresie se va folosi o dimensiune a ferestrei de 256 de octeți (ca și cum wbits ar fi setat la 8). Pentru decompresie, depinde de format:RAWva folosi 256 de octeți (corespunzând lui wbits setat la 8).ZLIB(sauAUTOcu zlib detectat) va folosi valoarea din antetul zlib.GZIP(sauAUTOcu gzip detectat) va folosi 32 de kiloocteți (corespunzând lui wbits setat la 15).
Consultați notele despre dimensiunea ferestrei de mai jos pentru mai multe informații despre dimensiunea ferestrei și fluxurile zlib și gzip.
Dacă close este setat la
True, atunci fluxul subiacent va fi închis automat când fluxuldeflate.DeflateIOeste închis. Acest lucru este util dacă doriți să returnați un fluxdeflate.DeflateIOcare încapsulează un alt flux, fără ca apelantul să trebuiască să se ocupe de gestionarea fluxului subiacent.Dacă compresia este activată, o instanță
deflate.DeflateIOdată acceptă atât citirea, cât și scrierea. De exemplu, un flux bidirecțional precum un socket poate fi încapsulat, ceea ce permite compresia/decompresia în ambele direcții.
Constante¶
Cele patru constante format selectează încadrarea aplicată în jurul fluxului de biți deflate brut.
- deflate.AUTO: int¶
Pentru decompresie, detectează automat formatul de intrare inspectând primii octeți ai fluxului (zlib sau gzip). Pentru compresie, generează un flux deflate brut fără antet sau încheiere (echivalent cu
RAW).
- deflate.RAW: int¶
Un flux deflate brut (fără antet, fără încheiere, fără sumă de control). Deoarece fluxul nu conține metadate, decompresorul nu poate recupera dimensiunea ferestrei din date, așa că wbits ar trebui setat explicit la decompresie – altfel fereastra implicită de 256 de octeți poate fi prea mică.
- deflate.ZLIB: int¶
Un flux deflate încapsulat în zlib, conform definiției din RFC 1950: un antet de 2 octeți care înregistrează dimensiunea ferestrei, payload-ul deflate și o sumă de control Adler-32 la final. Compact și autodescriptiv; foarte potrivit pentru utilizarea în sisteme încorporate.
- deflate.GZIP: int¶
Un flux deflate încapsulat în gzip, conform definiției din RFC 1952: un antet cu metadate opționale de nume de fișier/marcaj temporal, payload-ul deflate și un CRC-32 la final plus lungimea necomprimată. Acesta este formatul produs de utilitarul de linie de comandă
gzipși degzip.GzipFile. Antetul nu înregistrează dimensiunea ferestrei, așa că decompresorul trebuie să presupună 32 KiB dacă wbits nu este setat.
Exemple¶
Un caz tipic de utilizare pentru deflate.DeflateIO este citirea sau scrierea unui fișier comprimat din stocare:
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.
Deoarece deflate.DeflateIO este un flux, poate fi folosit, de exemplu, cu json.dump() și json.load() (precum și în orice alt loc unde pot fi folosite fluxuri):
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)
Dacă datele dvs. sursă nu sunt într-un format de flux, puteți folosi io.BytesIO pentru a le transforma într-un flux potrivit pentru utilizarea cu deflate.DeflateIO:
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()
Dimensiunea ferestrei deflate¶
Dimensiunea ferestrei limitează cât de departe în flux poate face referire (de)compresorul. Mărirea dimensiunii ferestrei va îmbunătăți compresia, dar va necesita mai multă memorie și va încetini compresorul.
Dacă un flux de intrare a fost comprimat cu o anumită dimensiune a ferestrei, atunci DeflateIO care folosește o dimensiune mai mică a ferestrei va eșua la jumătatea decompresiei cu OSError, dar numai dacă o referință înapoi face efectiv trimitere mai departe decât dimensiunea ferestrei decompresorului. Aceasta înseamnă că ar putea fi posibilă decompresia cu o dimensiune mai mică a ferestrei. De exemplu, acest lucru ar fi în mod evident valabil dacă datele necomprimate originale sunt mai scurte decât dimensiunea ferestrei.
Decompresie¶
Formatul zlib include un antet care specifică dimensiunea ferestrei folosită pentru comprimarea datelor. Acesta indică dimensiunea maximă a ferestrei necesară pentru decompresia acestui flux. Dacă această valoare din antet este mai mică decât valoarea wbits specificată (sau dacă wbits nu este setat), atunci se va folosi valoarea din antet.
Formatul gzip nu include dimensiunea ferestrei în antet și presupune că toate compresoarele gzip (de exemplu, utilitarul gzip sau implementarea gzip.GzipFile din CPython) folosesc dimensiunea maximă a ferestrei de 32 KiB. Din acest motiv, dacă parametrul wbits nu este setat, decompresorul va folosi o dimensiune a ferestrei de 32 KiB (corespunzând lui wbits setat la 15). Aceasta înseamnă că, pentru a putea decomprima un flux gzip arbitrar, trebuie să aveți disponibilă cel puțin această cantitate de RAM. Dacă aveți control asupra datelor sursă, luați în considerare în schimb utilizarea formatului zlib cu o dimensiune mai mică a ferestrei.
Formatul brut nu are antet și, prin urmare, nu include nicio informație despre dimensiunea ferestrei. Dacă wbits nu este setat, atunci va avea implicit o dimensiune a ferestrei de 256 de octeți, care poate să nu fie suficient de mare pentru un anumit flux. Prin urmare, se recomandă să setați întotdeauna explicit wbits dacă folosiți formatul brut.
Compresie¶
Pentru compresie, MicroPython va folosi implicit o dimensiune a ferestrei de 256 de octeți pentru toate formatele. Aceasta oferă un nivel rezonabil de compresie cu utilizare minimă a memoriei și timp de compresie rapid și va genera o ieșire care va funcționa cu orice decompresor.