Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

การบีบอัดด้วยอัลกอริทึม LZMA ใน Python (lzma)

อัลกอริทึม Lempel–Ziv–Markov chain algorithm (LZMA) ดำเนินการบีบอัดข้อมูลแบบไม่สูญเสีย (lossless) โดยใช้แผนการบีบอัดแบบดิกชันนารี (dictionary compression scheme) ที่มีอัตราส่วนการบีบอัดสูงกว่าอัลกอริทึมการบีบอัดอื่นๆ โมดูล lzma ของ Python ประกอบด้วยคลาสและฟังก์ชันสะดวกสำหรับการบีบอัดและแยกบีบอัดข้อมูลด้วยอัลกอริทึม LZMA

แม้ว่าฟังก์ชันในโมดูลนี้จะคล้ายกับโมดูล bz2 แต่คลาส LZMAFile ไม่ได้เป็น thread-safe เทียบเท่ากับคลาส BZ2File

ที่นี่อีกครั้ง ฟังก์ชัน open() ในโมดูล lzma เป็นวิธีง่ายที่สุดในการเปิดอ็อบเจ็กต์ไฟล์ที่บีบอัด LZMA

open()

ฟังก์ชันนี้เปิดไฟล์ที่บีบอัด LZMA และคืนค่าอ็อบเจ็กต์ไฟล์ ฟังก์ชันต้องการ 2 พารามิเตอร์หลัก - ชื่อไฟล์ และ mode พารามิเตอร์ mode ค่าเริ่มต้นคือ "rb" แต่สามารถรับค่าใดๆ จากต่อไปนี้:

binary mode - "r", "rb", "w", "wb", "x", "xb", "a" or "ab"
text mode - "rt", "wt", "xt", or "at"

compress()

ฟังก์ชันนี้บีบอัดข้อมูลที่ให้มาด้วยอัลกอริทึม LZMA และคืนค่าอ็อบเจ็กต์ไบต์ ฟังก์ชันนี้อาจมีอาร์กิวเมนต์ format ที่ตัดสินใจรูปแบบคอนเทนเนอร์ ค่าที่เป็นไปได้คือ FORMAT_XZ (ค่าเริ่มต้น) และ FORMAT_ALONE

decompress()

ฟังก์ชันนี้แยกบีบอัดข้อมูลและคืนค่าอ็อบเจ็กต์ไบต์ที่ไม่ได้บีบอัด

ฟังก์ชันข้างต้นใช้ในตัวอย่างต่อไปนี้ เพื่อเขียนข้อมูลที่บีบอัด LZMA ลงไฟล์:

>>> import lzma
>>> data = b"Welcome to TutorialsPoint"
>>> f = lzma.open("test.xz", "wb")
>>> f.write(data)
>>> f.close()

ไฟล์ 'test.xz' จะถูกสร้างในไดเรกทอรีทำงานปัจจุบัน เพื่อดึงข้อมูลที่ไม่ได้บีบอัดจากไฟล์นี้ ใช้โค้ดต่อไปนี้:

>>> import lzma
>>> f = lzma.open("test.xz", "rb")
>>> data = f.read()
>>> data
b'Welcome to TutorialsPoint'

เพื่อดำเนินการบีบอัดโดยใช้ API แบบเชิงวัตถุของโมดูล lzma เราต้องใช้คลาส LZMAFile:

LZMAFile()

นี่คือคอนสตรัคเตอร์สำหรับคลาส LZMAFile ต้องระบุไฟล์และ mode อ็อบเจ็กต์ที่มี mode 'w' หรือ 'wb' ทำให้เมธอด write() พร้อมใช้งาน

write()

เมธอดนี้บีบอัดข้อมูลที่ให้มาและเขียนลงในไฟล์ที่อยู่ด้านล่าง:

>>> data = b'Welcome to TutorialsPoint'
>>> obj = lzma.LZMAFile("test.xz", mode="wb")
>>> obj.write(data)
>>> obj.close()

ไฟล์ที่บีบอัดถูกอ่านและข้อมูลที่ไม่ได้บีบอัดถูกดึงคืนโดยเมธอด read() ของอ็อบเจ็กต์ LZMAFile ที่สร้างด้วยพารามิเตอร์ mode='rb':

read()

เมธอดนี้อ่านข้อมูลจากไฟล์ที่บีบอัดและคืนค่าข้อมูลที่ไม่ได้บีบอัด:

>>> obj = lzma.LZMAFile("test.xz", mode="rb")
>>> data = obj.read()
>>> data
b'Welcome to TutorialsPoint'

อัลกอริทึม LZMA อนุญาตให้เขียนข้อมูลที่บีบอัดลงในไฟล์ที่เปิดอยู่แล้วได้อีกด้วย ในตัวอย่างต่อไปนี้ 'test.txt' ถูกเปิดอย่างปกติ (โดยใช้ฟังก์ชันสำเร็จรูป open()) ในโหมด 'wb' และข้อความบางส่วนถูกเขียนลงไป หลังจากนั้น ไฟล์เดียวกันถูกใช้เพื่อเขียนข้อมูลที่บีบอัด:

>>> f = open("test.txt", "wb")
>>> f.write(b"Hello world")
>>> fp = lzma.open(f, "wb")
>>> fp.write(b"Welcome to Python")
>>> f.write(b"Thank you")
>>> f.close()
>>> fp.flush()
>>> fp.close()

เมื่อรันโค้ดข้างต้น ไฟล์ 'test.txt' จะปรากฏในไดเรกทอรีปัจจุบัน มันประกอบด้วยข้อมูลผสมของบีบอัดและไม่บีบอัด ดังนี้:

Hello worldý7zXZ æÖ´F!t/å£Thank you

เหมือนกับโมดูล bzma โมดูล lzma ก็มี incremental compressor และ decompressor classes ด้วย:

LZMACompressor()

นี่คือคอนสตรัคเตอร์ที่คืนค่าอ็อบเจ็กต์ compressor แบบเพิ่มขึ้น (incremental) หลายชิ้น (chunks) สามารถบีบอัดแยกต่างหาก และข้อมูลที่ต่อกันถูกเขียนลงไฟล์

compress()

เมธอดนี้บีบอัดข้อมูลที่ให้มาและคืนค่าอ็อบเจ็กต์ไบต์

flush()

เมธอดนี้ว่างเปล่าบัฟเฟอร์และคืนค่าอ็อบเจ็กต์ไบต์

ตัวอย่างต่อไปนี้บีบอัดอ็อบเจ็กต์ลิสต์โดยใช้ incremental compressor object:

>>> data = [b'Hello World', b'How are you?', b'welcome to Python']
>>> obj = lzma.LZMACompressor()
>>> bindata = []
>>> for i in data:
...     bindata.append(obj.compress(i))
>>> bindata.append(obj.flush())
>>> bindata
[b'\xfd7zXZ\x00\x00\x04\xe6\xd6\xb4F\x02\x00!\x01\x16\x00\x00\x00t/\xe5\xa3', b'', b'', b"\x01\x00'Hello WorldHow are you?welcome to Python\x00\xf5\xc6\xc1d|\xf3\x8ey\x00\x01@(\xd4RJ\xe5\x1f\xb6\xf3}\x01\x00\x00\x00\x00\x04YZ"]

โค้ดข้างต้นสร้าง bindata เป็นรายการของการแสดงไบต์ที่บีบอัดของแต่ละรายการในลิสต์ต้นฉบับ เพื่อดึงข้อมูลที่ไม่ได้บีบอัดโดยใช้ LZMADecompressor object ใช้คำสั่งต่อไปนี้:

>>> obj = lzma.LZMADecompressor()
>>> binstr = b''.join(bindata)
>>> obj.decompress(binstr)
b'Hello WorldHow are you?welcome to Python'

ในบทความนี้ คลาสและฟังก์ชันในโมดูล lzma ได้รับการอธิบายพร้อมตัวอย่าง