deflate --- การบีบอัดและคลายการบีบอัด deflate¶
โมดูลนี้รองรับการบีบอัดและคลายการบีบอัดข้อมูลไบนารีด้วย อัลกอริทึม DEFLATE (ที่ใช้กันทั่วไปใน zlib library และโปรแกรม 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 ซึ่งเป็นออบเจกต์ คล้าย stream เช่น ไฟล์, socket หรือ stream (รวมถึง
io.BytesIO) คลาสนี้เองก็เป็น stream และรองรับเมธอด read/readinto/write/close มาตรฐานstream ต้องเป็น blocking stream ปัจจุบันยังไม่รองรับ non-blocking stream
format สามารถกำหนดเป็นค่าคงที่ใดก็ได้ที่นิยามไว้ด้านล่าง และค่าเริ่มต้นคือ
AUTOซึ่งสำหรับการคลายการบีบอัดจะตรวจจับรูปแบบ gzip หรือ zlib โดยอัตโนมัติ และสำหรับการบีบอัดจะสร้าง raw streamพารามิเตอร์ wbits กำหนดลอการิทึมฐาน 2 ของขนาดหน้าต่าง DEFLATE dictionary เช่น การตั้ง wbits เป็น
10จะกำหนดขนาดหน้าต่างเป็น 1024 ไบต์ ค่าที่ถูกต้องคือ5ถึง15รวม (สอดคล้องกับขนาดหน้าต่าง 32 ถึง 32k ไบต์)ถ้า wbits ถูกตั้งเป็น
0(ค่าเริ่มต้น) สำหรับการบีบอัดจะใช้ขนาดหน้าต่าง 256 ไบต์ (เหมือนกับตั้ง wbits เป็น 8) สำหรับการคลายการบีบอัดขึ้นอยู่กับรูปแบบ:RAWจะใช้ 256 ไบต์ (สอดคล้องกับ wbits ที่ตั้งเป็น 8)ZLIB(หรือAUTOเมื่อตรวจจับ zlib ได้) จะใช้ค่าจาก zlib headerGZIP(หรือAUTOเมื่อตรวจจับ gzip ได้) จะใช้ 32 กิโลไบต์ (สอดคล้องกับ wbits ที่ตั้งเป็น 15)
ดูหมายเหตุ ขนาดหน้าต่าง ด้านล่างสำหรับข้อมูลเพิ่มเติมเกี่ยวกับขนาดหน้าต่าง, zlib และ gzip stream
ถ้า close ถูกตั้งเป็น
Truestream ต้นแบบจะถูกปิดโดยอัตโนมัติเมื่อปิด streamdeflate.DeflateIOสิ่งนี้มีประโยชน์เมื่อต้องการคืนค่า streamdeflate.DeflateIOที่ห่อหุ้ม stream อื่น โดยไม่ต้องให้ผู้เรียกจัดการ stream ต้นแบบเองถ้าเปิดใช้งานการบีบอัด อินสแตนซ์
deflate.DeflateIOที่กำหนดรองรับทั้งการอ่านและเขียน เช่น สามารถห่อหุ้ม stream สองทิศทางอย่าง socket เพื่อบีบอัด/คลายการบีบอัดในทั้งสองทิศทาง
ค่าคงที่¶
ค่าคงที่ format ทั้งสี่เลือกการกรอบที่ใช้กับ raw deflate bit-stream
- deflate.AUTO: int¶
สำหรับการคลายการบีบอัด ตรวจจับรูปแบบอินพุตโดยอัตโนมัติด้วยการตรวจสอบไบต์แรกของ stream (zlib หรือ gzip) สำหรับการบีบอัด สร้าง raw deflate stream โดยไม่มี header หรือ trailer (เทียบเท่า
RAW)
- deflate.RAW: int¶
Raw deflate stream (ไม่มี header, ไม่มี trailer, ไม่มี checksum) เนื่องจาก stream ไม่มี metadata ตัวคลายการบีบอัดไม่สามารถกู้คืนขนาดหน้าต่างจากข้อมูล ดังนั้นควรตั้ง wbits อย่างชัดเจนเมื่อคลายการบีบอัด มิฉะนั้นค่าเริ่มต้น 256 ไบต์อาจน้อยเกินไป
- deflate.ZLIB: int¶
A zlib-wrapped deflate stream ตามที่นิยามใน RFC 1950: header 2 ไบต์ที่บันทึกขนาดหน้าต่าง, deflate payload และ checksum Adler-32 ท้าย กะทัดรัดและอธิบายตัวเองได้; เหมาะสำหรับการใช้งานแบบ embedded
- deflate.GZIP: int¶
A gzip-wrapped deflate stream ตามที่นิยามใน RFC 1952: header พร้อม metadata ชื่อไฟล์/timestamp ที่เป็นตัวเลือก, deflate payload และ CRC-32 พร้อมความยาวที่ไม่บีบอัดท้าย นี่คือรูปแบบที่สร้างโดยเครื่องมือคำสั่ง
gzipและgzip.GzipFileheader ไม่บันทึกขนาดหน้าต่าง ดังนั้นตัวคลายการบีบอัดต้องสมมติ 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 เป็น stream จึงสามารถใช้ร่วมกับ json.dump() และ json.load() (และที่อื่น ๆ ที่ใช้ stream ได้) ตัวอย่างเช่น:
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)
ถ้าข้อมูลต้นทางไม่อยู่ในรูปแบบ stream สามารถใช้ io.BytesIO เพื่อแปลงเป็น stream ที่เหมาะสำหรับใช้กับ 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¶
ขนาดหน้าต่างจำกัดว่าตัว (คลาย)บีบอัดสามารถอ้างอิงย้อนกลับได้ไกลแค่ไหนใน stream การเพิ่มขนาดหน้าต่างจะปรับปรุงการบีบอัด แต่ต้องการหน่วยความจำมากขึ้นและทำให้การบีบอัดช้าลง
ถ้า input stream ถูกบีบอัดด้วยขนาดหน้าต่างที่กำหนด การใช้ DeflateIO ที่มีขนาดหน้าต่างน้อยกว่าจะล้มเหลวระหว่างการคลายการบีบอัดด้วย OSError แต่เฉพาะเมื่อมีการอ้างอิงย้อนกลับที่เกินขนาดหน้าต่างของตัวคลายการบีบอัด ซึ่งหมายความว่าอาจสามารถคลายการบีบอัดด้วยขนาดหน้าต่างน้อยกว่าได้ เช่น จะเป็นไปได้ง่ายหากข้อมูลต้นฉบับที่ไม่บีบอัดสั้นกว่าขนาดหน้าต่าง
การคลายการบีบอัด¶
รูปแบบ zlib มี header ที่ระบุขนาดหน้าต่างที่ใช้บีบอัดข้อมูล ค่านี้บ่งบอกขนาดหน้าต่างสูงสุดที่ต้องการเพื่อคลายการบีบอัด stream นี้ ถ้าค่า header นี้น้อยกว่าค่า wbits ที่ระบุ (หรือถ้าไม่ได้ตั้ง wbits) ค่าใน header จะถูกใช้แทน
รูปแบบ gzip ไม่รวมขนาดหน้าต่างใน header และสมมติว่าตัวบีบอัด gzip ทั้งหมด (เช่น ยูทิลิตี gzip หรือการใช้งาน gzip.GzipFile ของ CPython) ใช้ขนาดหน้าต่างสูงสุด 32kiB ด้วยเหตุนี้ ถ้าไม่ตั้งพารามิเตอร์ wbits ตัวคลายการบีบอัดจะใช้ขนาดหน้าต่าง 32 kiB (สอดคล้องกับ wbits ที่ตั้งเป็น 15) หมายความว่าหากต้องการคลายการบีบอัด gzip stream ใด ๆ จำเป็นต้องมี RAM อย่างน้อยเท่านี้ หากควบคุมข้อมูลต้นทางได้ ควรพิจารณาใช้รูปแบบ zlib ที่มีขนาดหน้าต่างน้อยกว่าแทน
รูปแบบ raw ไม่มี header จึงไม่มีข้อมูลเกี่ยวกับขนาดหน้าต่าง ถ้าไม่ตั้ง wbits จะใช้ขนาดหน้าต่าง 256 ไบต์เป็นค่าเริ่มต้น ซึ่งอาจไม่พอสำหรับบาง stream จึงแนะนำให้ตั้ง wbits อย่างชัดเจนเสมอเมื่อใช้รูปแบบ raw
การบีบอัด¶
สำหรับการบีบอัด MicroPython จะใช้ขนาดหน้าต่าง 256 ไบต์เป็นค่าเริ่มต้นสำหรับทุกรูปแบบ ซึ่งให้การบีบอัดในระดับที่เหมาะสมโดยใช้หน่วยความจำน้อยและเวลาบีบอัดรวดเร็ว และจะสร้างผลลัพธ์ที่ใช้งานได้กับตัวคลายการบีบอัดทุกตัว