deflate — דחיסה ופענוח deflate¶
מודול זה מאפשר דחיסה ופענוח של נתונים בינאריים באמצעות אלגוריתם DEFLATE (הנפוץ בספריית zlib ובמארכב gzip). נוסף ב-MicroPython v1.21.
זמינות בלוחות הנתמכים על ידי OpenMV:
לוח |
פענוח |
דחיסה |
|---|---|---|
OpenMV Cam N6 |
כן |
לא |
OpenMV AE3 |
כן |
כן |
OpenMV Cam RT1062 |
כן |
כן |
OpenMV Cam Pure Thermal |
כן |
לא |
OpenMV Cam M4 |
כן |
לא |
OpenMV Cam M7 |
כן |
לא |
OpenMV Cam H7 |
כן |
לא |
OpenMV Cam H7 Plus |
כן |
לא |
Arduino Giga |
כן |
לא |
Arduino Portenta H7 |
כן |
לא |
Arduino Nicla Vision |
כן |
לא |
Arduino Nano 33 BLE Sense |
כן |
לא |
Arduino Nano RP2040 Connect |
כן |
לא |
מחלקות¶
- class deflate.DeflateIO(stream: Any, format: int = AUTO, wbits: int = 0, close: bool = False, /)¶
ניתן להשתמש במחלקה זו כדי לעטוף stream שהוא כל אובייקט דמוי-זרם כגון קובץ, socket, או זרם (כולל
io.BytesIO). היא עצמה זרם ומממשת את המתודות הסטנדרטיות read/readinto/write/close.ה-stream חייב להיות זרם חוסם. זרמים לא-חוסמים אינם נתמכים כעת.
ניתן להגדיר את ה-format לכל אחד מהקבועים המוגדרים להלן, וברירת המחדל היא
AUTOאשר עבור פענוח תזהה אוטומטית זרמי gzip או zlib, ועבור דחיסה תפיק זרם גולמי.הפרמטר wbits קובע את הלוגריתם בבסיס 2 של גודל חלון מילון ה-DEFLATE. כך למשל, הגדרת wbits ל-
10קובעת את גודל החלון ל-1024 בתים. ערכים חוקיים הם5עד15ועד בכלל (המתאימים לגדלי חלון של 32 עד 32k בתים).אם wbits מוגדר ל-
0(ברירת המחדל), אזי עבור דחיסה יעשה שימוש בגודל חלון של 256 בתים (כאילו wbits הוגדר ל-8). עבור פענוח, הדבר תלוי בפורמט:RAWישתמש ב-256 בתים (המתאימים ל-wbits שהוגדר ל-8).ZLIB(אוAUTOעם זיהוי zlib) ישתמש בערך מכותרת ה-zlib.GZIP(אוAUTOעם זיהוי gzip) ישתמש ב-32 קילובתים (המתאימים ל-wbits שהוגדר ל-15).
ראו את הערות גודל החלון להלן למידע נוסף על גודל החלון, וזרמי zlib ו-gzip.
אם close מוגדר ל-
Trueאזי הזרם הבסיסי ייסגר אוטומטית כאשר זרם ה-deflate.DeflateIOנסגר. הדבר שימושי אם ברצונכם להחזיר זרםdeflate.DeflateIOשעוטף זרם אחר, מבלי שהקורא יצטרך לדעת על ניהול הזרם הבסיסי.אם הדחיסה מופעלת, מופע נתון של
deflate.DeflateIOתומך הן בקריאה והן בכתיבה. לדוגמה, ניתן לעטוף זרם דו-כיווני כגון socket, מה שמאפשר דחיסה/פענוח בשני הכיוונים.
קבועים¶
ארבעת קבועי ה-format בוחרים את המסגרת המיושמת סביב זרם הסיביות הגולמי של deflate.
- deflate.AUTO: int¶
עבור פענוח, זהה אוטומטית את פורמט הקלט על ידי בדיקת הבתים הראשונים של הזרם (zlib או gzip). עבור דחיסה, הפק זרם deflate גולמי ללא כותרת או נספח (שווה ערך ל-
RAW).
- deflate.RAW: int¶
זרם deflate גולמי (ללא כותרת, ללא נספח, ללא סכום בדיקה). מכיוון שהזרם אינו מכיל מטא-נתונים, המפענח אינו יכול לשחזר את גודל החלון מהנתונים, ולכן יש להגדיר את wbits במפורש בעת הפענוח – אחרת חלון ברירת המחדל בן 256 הבתים עלול להיות קטן מדי.
- deflate.ZLIB: int¶
זרם deflate עטוף ב-zlib כפי שמוגדר ב-RFC 1950: כותרת בת 2 בתים הרושמת את גודל החלון, מטען ה-deflate, וסכום בדיקה Adler-32 בנספח. קומפקטי ומתאר את עצמו; מתאים היטב לשימוש משובץ.
- deflate.GZIP: int¶
זרם deflate עטוף ב-gzip כפי שמוגדר ב-RFC 1952: כותרת עם מטא-נתונים אופציונליים של שם קובץ/חותמת זמן, מטען ה-deflate, ובנספח CRC-32 בתוספת אורך לא-דחוס. זהו הפורמט המופק על ידי כלי שורת הפקודה
gzipועל ידיgzip.GzipFile. הכותרת אינה רושמת את גודל החלון, ולכן המפענח חייב להניח 32 KiB אלא אם wbits מוגדר.
דוגמאות¶
מקרה שימוש טיפוסי עבור deflate.DeflateIO הוא קריאה או כתיבה של קובץ דחוס מאחסון:
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.
מכיוון ש-deflate.DeflateIO הוא זרם, ניתן להשתמש בו למשל עם json.dump() ו-json.load() (ובכל מקום אחר שבו ניתן להשתמש בזרמים):
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)
אם נתוני המקור שלכם אינם בפורמט זרם, ניתן להשתמש ב-io.BytesIO כדי להפוך אותם לזרם המתאים לשימוש עם 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()
גודל חלון Deflate¶
גודל החלון מגביל עד כמה רחוק לאחור בזרם יכול הדוחס/המפענח להפנות. הגדלת גודל החלון תשפר את הדחיסה, אך תדרוש יותר זיכרון ותאט את הדוחס.
אם זרם קלט נדחס בגודל חלון נתון, אזי DeflateIO המשתמש בגודל חלון קטן יותר ייכשל באמצע הפענוח עם OSError, אך רק אם הפניה לאחור אכן מפנה רחוק יותר מגודל החלון של המפענח. משמעות הדבר היא שייתכן שאפשר יהיה לפענח בגודל חלון קטן יותר. לדוגמה, זה יהיה המקרה באופן טריוויאלי אם הנתונים המקוריים הלא-דחוסים קצרים יותר מגודל החלון.
פענוח¶
פורמט ה-zlib כולל כותרת המציינת את גודל החלון ששימש לדחיסת הנתונים. זה מציין את גודל החלון המרבי הנדרש לפענוח זרם זה. אם ערך כותרת זה קטן מערך ה-wbits שצוין (או אם wbits אינו מוגדר), אזי ייעשה שימוש בערך הכותרת.
פורמט ה-gzip אינו כולל את גודל החלון בכותרת, ומניח שכל דוחסי ה-gzip (למשל כלי השירות gzip, או מימוש ה-gzip.GzipFile של CPython) משתמשים בגודל החלון המרבי של 32kiB. מסיבה זו, אם הפרמטר wbits אינו מוגדר, המפענח ישתמש בגודל חלון של 32 kiB (המתאים ל-wbits שהוגדר ל-15). משמעות הדבר היא שכדי להיות מסוגלים לפענח זרם gzip שרירותי, עליכם שיהיה זמין לכל הפחות כמות זיכרון RAM זו. אם אתם שולטים בנתוני המקור, שקלו במקום זאת להשתמש בפורמט zlib עם גודל חלון קטן יותר.
לפורמט הגולמי אין כותרת ולכן הוא אינו כולל מידע כלשהו על גודל החלון. אם wbits אינו מוגדר, אזי ברירת המחדל תהיה גודל חלון של 256 בתים, שעלול שלא להיות גדול דיו עבור זרם נתון. לפיכך מומלץ שתמיד תגדירו במפורש את wbits בעת שימוש בפורמט הגולמי.
דחיסה¶
עבור דחיסה, MicroPython יקבע כברירת מחדל גודל חלון של 256 בתים עבור כל הפורמטים. זה מספק כמות סבירה של דחיסה עם שימוש מינימלי בזיכרון וזמן דחיסה מהיר, ויפיק פלט שיעבוד עם כל מפענח.