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 وهو أي كائن شبيه بالتدفق مثل ملف أو مقبس أو تدفق (بما في ذلك
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معينة تدعم القراءة والكتابة معاً. فعلى سبيل المثال، يمكن تغليف تدفق ثنائي الاتجاه مثل المقبس، مما يتيح الضغط/فك الضغط في كلا الاتجاهين.
الثوابت¶
تختار ثوابت 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 كيبي بايت ما لم يُضبط 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، أو تنفيذ CPython لـ gzip.GzipFile) تستخدم أقصى حجم نافذة وهو 32 كيبي بايت. ولهذا السبب، إذا لم يُضبط المعطى wbits، فإن أداة فك الضغط ستستخدم حجم نافذة قدره 32 كيبي بايت (المقابل لضبط wbits على 15). وهذا يعني أنه لتتمكن من فك ضغط أي تدفق gzip اعتباطي، يجب أن يتوفر لديك على الأقل هذا القدر من ذاكرة RAM. وإذا كنت تتحكم في بيانات المصدر، ففكّر بدلاً من ذلك في استخدام تنسيق zlib بحجم نافذة أصغر.
ليس للتنسيق الخام ترويسة، ولذلك لا يتضمن أي معلومات عن حجم النافذة. وإذا لم يُضبط wbits، فسيكون افتراضياً بحجم نافذة قدره 256 بايت، وقد لا يكون كبيراً بما يكفي لتدفق معين. ولذلك يُنصح بأن تضبط wbits صراحة دائماً عند استخدام التنسيق الخام.
الضغط¶
بالنسبة للضغط، سيستخدم MicroPython افتراضياً حجم نافذة قدره 256 بايت لجميع التنسيقات. وهذا يوفر قدراً معقولاً من الضغط مع استخدام أدنى للذاكرة وزمن ضغط سريع، وسيولّد خرجاً يعمل مع أي أداة فك ضغط.