bz2 --- پشتیبانی از فشرده‌سازی bzip2

کد منبع: Lib/bz2.py


این ماژول یک رابط جامع برای فشرده‌سازی و واگشایی داده‌ها با استفاده از الگوریتم فشرده‌سازی bzip2 فراهم می‌کند.

ماژول bz2 شامل موارد زیر است:

  • تابع open() و کلاس BZ2File برای خواندن و نوشتن پرونده‌های فشرده.

  • کلاس‌های BZ2Compressor و BZ2Decompressor برای فشرده‌سازی/واگشایی تدریجی.

  • توابع compress() و decompress() برای فشرده‌سازی/واگشایی یک‌باره.

این یک optional module است. اگر در نسخه CPython شما وجود ندارد، برای مستندات به توزیع‌کننده خود (یعنی هر کسی که پایتون را در اختیار شما قرار داده است) مراجعه کنید. اگر شما توزیع‌کننده هستید، نیازمندی‌های ماژول‌های اختیاری را ببینید.

فشرده‌سازی و واگشایی پرونده‌ها

bz2.open(filename, mode='rb', compresslevel=9, encoding=None, errors=None, newline=None)

یک پرونده فشرده‌شده با bzip2 را در حالت دودویی یا متنی باز می‌کند و یک file object بازمی‌گرداند.

مانند سازنده‌ی BZ2File، آرگومان filename می‌تواند یک نام پرونده واقعی (یک شیء str یا bytes)، یا یک شیء پرونده موجود برای خواندن از آن یا نوشتن در آن باشد.

آرگومان mode می‌تواند برای حالت دودویی هر یک از 'r'، 'rb'، 'w'، 'wb'، 'x'، 'xb'، 'a' یا 'ab'، یا برای حالت متنی هر یک از 'rt'، 'wt'، 'xt' یا 'at' باشد. مقدار پیش‌فرض 'rb' است.

آرگومان compresslevel یک عدد صحیح از ۱ تا ۹ است، همان‌طور که برای سازنده‌ی BZ2File نیز وجود دارد.

برای حالت دودویی، این تابع معادل سازنده‌ی BZ2File است: BZ2File(filename, mode, compresslevel=compresslevel). در این حالت، نباید آرگومان‌های encoding، errors و newline ارائه شوند.

برای حالت متنی، یک شیء BZ2File ایجاد می‌شود و در نمونه‌ای از io.TextIOWrapper با کدگذاری، رفتار مدیریت خطا و پایان(های) خط مشخص‌شده، دربرگرفته می‌شود.

اضافه شده در نسخه‌ی 3.3.

تغییر یافته در نسخه‌ی 3.4: حالت 'x' (ایجاد انحصاری) افزوده شد.

تغییر یافته در نسخه‌ی 3.6: یک path-like object را می‌پذیرد.

class bz2.BZ2File(filename, mode='r', *, compresslevel=9)

باز کردن یک پرونده فشرده‌شده با bzip2 در حالت دودویی.

اگر filename یک شیء str یا bytes باشد، پرونده نام‌گذاری‌شده مستقیماً باز می‌شود. در غیر این صورت، filename باید یک file object باشد که برای خواندن یا نوشتن داده‌های فشرده استفاده می‌شود.

آرگومان mode می‌تواند 'r' برای خواندن (پیش‌فرض)، 'w' برای بازنویسی، 'x' برای ایجاد انحصاری، یا 'a' برای الحاق باشد. این موارد می‌توانند به‌طور معادل به‌ترتیب به‌صورت 'rb'، 'wb'، 'xb' و 'ab' داده شوند.

اگر filename یک شیء پرونده باشد (نه یک نام پرونده واقعی)، حالت 'w' پرونده را کوتاه نمی‌کند و در عوض معادل 'a' است.

اگر mode برابر 'w' یا 'a' باشد، compresslevel می‌تواند عدد صحیحی بین 1 و 9 باشد که سطح فشرده‌سازی را مشخص می‌کند: 1 کمترین میزان فشرده‌سازی را ایجاد می‌کند و 9 (پیش‌فرض) بیشترین میزان فشرده‌سازی را ایجاد می‌کند.

اگر mode برابر 'r' باشد، پرونده ورودی ممکن است حاصل الحاق چند جریان فشرده باشد.

کلاس BZ2File تمام اعضای مشخص‌شده توسط io.BufferedIOBase را فراهم می‌کند، به‌جز detach() و truncate(). پیمایش و دستور with پشتیبانی می‌شوند.

BZ2File همچنین متدها و ویژگی‌های زیر را ارائه می‌دهد:

peek([n])

داده‌های بافرشده را بدون جلو بردن موقعیت پرونده برمی‌گرداند. حداقل یک بایت داده برگردانده خواهد شد (مگر در EOF). تعداد دقیق بایت‌های برگردانده‌شده نامشخص است.

توجه

اگرچه فراخوانی peek() موقعیت فایلِ BZ2File را تغییر نمی‌دهد، اما ممکن است موقعیت شیء پرونده زیربنایی را تغییر دهد (برای مثال، اگر BZ2File با ارسال یک شیء پرونده برای filename ساخته شده باشد).

اضافه شده در نسخه‌ی 3.3.

fileno()

توصیف‌گر پرونده مربوط به پرونده زیربنایی را برمی‌گرداند.

اضافه شده در نسخه‌ی 3.3.

readable()

برمی‌گرداند که آیا پرونده برای خواندن باز شده است.

اضافه شده در نسخه‌ی 3.3.

seekable()

برمی‌گرداند که آیا پرونده از مکان‌یابی (seeking) پشتیبانی می‌کند.

اضافه شده در نسخه‌ی 3.3.

writable()

برمی‌گرداند که آیا پرونده برای نوشتن باز شده است یا خیر.

اضافه شده در نسخه‌ی 3.3.

read1(size=-1)

تا size بایت فشرده‌نشده را می‌خواند، در حالی که تلاش می‌کند از انجام چندین عملیات خواندن از جریان زیرین اجتناب کند. اگر size منفی باشد، تا اندازه‌ی یک بافر داده می‌خواند.

اگر پرونده در EOF باشد، b'' را برمی‌گرداند.

اضافه شده در نسخه‌ی 3.3.

readinto(b)

بایت‌ها را در b بخوانید.

تعداد بایت‌های خوانده‌شده را برمی‌گرداند (۰ برای EOF).

اضافه شده در نسخه‌ی 3.3.

mode

'rb' برای خواندن و 'wb' برای نوشتن.

اضافه شده در نسخه‌ی 3.13.

name

نام پرونده bzip2. معادل ویژگی name در file object زیربنایی است.

اضافه شده در نسخه‌ی 3.13.

تغییر یافته در نسخه‌ی 3.1: پشتیبانی از دستور with افزوده شد.

تغییر یافته در نسخه‌ی 3.3: پشتیبانی برای اینکه filename به‌جای یک نام پرونده واقعی، یک file object باشد، اضافه شد.

حالت 'a' (الحاق) افزوده شد، به همراه پشتیبانی از خواندن پرونده‌های چندجریانی (multi-stream).

تغییر یافته در نسخه‌ی 3.4: حالت 'x' (ایجاد انحصاری) افزوده شد.

تغییر یافته در نسخه‌ی 3.5: متد read() اکنون آرگومانی با مقدار None را می‌پذیرد.

تغییر یافته در نسخه‌ی 3.6: یک path-like object را می‌پذیرد.

تغییر یافته در نسخه‌ی 3.9: پارامتر buffering حذف شده است. این پارامتر از Python 3.0 نادیده گرفته می‌شد و منسوخ بود. برای کنترل چگونگی باز شدن پرونده، یک شیء پرونده باز را پاس دهید.

پارامتر compresslevel فقط کلیدواژه‌ای شد.

تغییر یافته در نسخه‌ی 3.10: این کلاس در مواجهه با چندین خواننده یا نویسنده همزمان، از نظر نخی ایمن نیست، همان‌طور که کلاس‌های معادل آن در gzip و lzma همیشه بوده‌اند.

فشرده‌سازی و واگشایی تدریجی

class bz2.BZ2Compressor(compresslevel=9)

یک شیء فشرده‌ساز جدید ایجاد کنید. این شیء می‌تواند برای فشرده‌سازی تدریجی داده‌ها استفاده شود. برای فشرده‌سازی یکجا، به‌جای آن از تابع compress() استفاده کنید.

compresslevel، در صورت داده شدن، باید یک عدد صحیح بین 1 و 9 باشد. مقدار پیش‌فرض 9 است.

compress(data)

داده را به شیء فشرده‌ساز ارائه دهید. در صورت امکان تکه‌ای از داده فشرده برمی‌گرداند، در غیر این صورت یک رشته بایتی خالی برمی‌گرداند.

هنگامی که ارائه داده به فشرده‌ساز را به پایان رساندید، متد flush() را فراخوانی کنید تا فرآیند فشرده‌سازی به پایان برسد.

flush()

فرایند فشرده‌سازی را به پایان می‌رساند. داده‌های فشرده‌ی باقی‌مانده در بافرهای داخلی را برمی‌گرداند.

پس از فراخوانی این متد، نمی‌توان از شیء فشرده‌ساز استفاده کرد.

class bz2.BZ2Decompressor

یک شیء واگشا (decompressor) جدید ایجاد کنید. این شیء می‌تواند برای واگشایی داده‌ها به‌صورت تدریجی استفاده شود. برای فشرده‌سازی یک‌باره، به‌جای آن از تابع decompress() استفاده کنید.

توجه

این کلاس، برخلاف decompress() و BZ2File، ورودی‌های حاوی چندین جریان فشرده را به‌صورت شفاف مدیریت نمی‌کند. اگر نیاز دارید یک ورودی حاوی چند جریان را با BZ2Decompressor واگشایی کنید، باید برای هر جریان از یک واگشای جدید استفاده کنید.

decompress(data, max_length=-1)

data (یک bytes-like object) را واگشایی می‌کند و داده‌ی فشرده‌نشده را به‌صورت بایت برمی‌گرداند. ممکن است بخشی از data در بافر داخلی نگه‌داری شود، تا در فراخوانی‌های بعدی decompress() استفاده شود. داده‌ی برگردانده‌شده باید با خروجی هر فراخوانی قبلی decompress() الحاق شود.

اگر max_length منفی نباشد، حداکثر max_length بایت از داده‌ی خارج‌شده از حالت فشرده را برمی‌گرداند. اگر به این حد برسد و امکان تولید خروجی بیشتری وجود داشته باشد، ویژگی needs_input روی False تنظیم می‌شود. در این حالت، می‌توانید در فراخوانی بعدی decompress() برای دریافت خروجی بیشتر، data را به‌صورت b'' ارائه دهید.

اگر تمام داده‌های ورودی واگشایی شده و بازگردانده شده باشند (چه به این دلیل که داده‌ها کمتر از max_length بایت بودند و چه به این دلیل که max_length منفی بود)، ویژگی needs_input روی True تنظیم خواهد شد.

تلاش برای واگشایی داده‌ها پس از رسیدن به پایان جریان، باعث پرتاب یک EOFError می‌شود. هر داده‌ای که پس از پایان جریان یافت شود، نادیده گرفته می‌شود و در ویژگی unused_data ذخیره می‌شود.

تغییر یافته در نسخه‌ی 3.5: پارامتر max_length افزوده شد.

eof

اگر به نشانگر پایان جریان رسیده باشد، True است.

اضافه شده در نسخه‌ی 3.3.

unused_data

داده‌ای پس از پایان جریان فشرده یافت شد.

اگر پیش از رسیدن به پایان جریان به این ویژگی دسترسی پیدا کنید، مقدار آن b'' خواهد بود.

needs_input

False اگر متد decompress() بتواند پیش از نیاز به ورودی فشرده‌نشده‌ی جدید، داده‌ی واگشایی‌شده‌ی بیشتری فراهم کند.

اضافه شده در نسخه‌ی 3.5.

فشرده‌سازی/واگشایی یک‌باره

bz2.compress(data, compresslevel=9)

فشرده‌سازی data، یک شیء شبه‌بایت.

compresslevel، در صورت داده شدن، باید یک عدد صحیح بین 1 و 9 باشد. مقدار پیش‌فرض 9 است.

برای فشرده‌سازی افزایشی، در عوض از BZ2Compressor استفاده کنید.

bz2.decompress(data)

واگشایی data، یک شیء شبه‌بایت (bytes-like object).

اگر data حاصل الحاق چندین جریان فشرده باشد، تمام جریان‌ها را از حالت فشرده خارج می‌کند.

برای واگشایی افزایشی، به‌جای آن از BZ2Decompressor استفاده کنید.

تغییر یافته در نسخه‌ی 3.3: پشتیبانی از ورودی‌های چندجریانی (multi-stream) اضافه شد.

نمونه‌های استفاده

در زیر چند نمونه از کاربرد معمول ماژول bz2 آمده است.

استفاده از compress() و decompress() برای نمایش فشرده‌سازی رفت‌وبرگشتی:

>>> import bz2
>>> data = b"""\
... Donec rhoncus quis sapien sit amet molestie. Fusce scelerisque vel augue
... nec ullamcorper. Nam rutrum pretium placerat. Aliquam vel tristique lorem,
... sit amet cursus ante. In interdum laoreet mi, sit amet ultrices purus
... pulvinar a. Nam gravida euismod magna, non varius justo tincidunt feugiat.
... Aliquam pharetra lacus non risus vehicula rutrum. Maecenas aliquam leo
... felis. Pellentesque semper nunc sit amet nibh ullamcorper, ac elementum
... dolor luctus. Curabitur lacinia mi ornare consectetur vestibulum."""
>>> c = bz2.compress(data)
>>> len(data) / len(c)  # Data compression ratio
1.513595166163142
>>> d = bz2.decompress(c)
>>> data == d  # Check equality to original object after round-trip
True

استفاده از BZ2Compressor برای فشرده‌سازی تدریجی:

>>> import bz2
>>> def gen_data(chunks=10, chunksize=1000):
...     """Yield incremental blocks of chunksize bytes."""
...     for _ in range(chunks):
...         yield b"z" * chunksize
...
>>> comp = bz2.BZ2Compressor()
>>> out = b""
>>> for chunk in gen_data():
...     # Provide data to the compressor object
...     out = out + comp.compress(chunk)
...
>>> # Finish the compression process.  Call this once you have
>>> # finished providing data to the compressor.
>>> out = out + comp.flush()

مثال بالا از یک جریان داده بسیار «غیرتصادفی» استفاده می‌کند (جریانی از تکه‌های b"z"). داده‌های تصادفی معمولاً به‌خوبی فشرده نمی‌شوند، در حالی که داده‌های منظم و تکراری معمولاً نسبت فشرده‌سازی بالایی دارند.

نوشتن و خواندن یک پرونده فشرده‌شده با bzip2 در حالت دودویی:

>>> import bz2
>>> data = b"""\
... Donec rhoncus quis sapien sit amet molestie. Fusce scelerisque vel augue
... nec ullamcorper. Nam rutrum pretium placerat. Aliquam vel tristique lorem,
... sit amet cursus ante. In interdum laoreet mi, sit amet ultrices purus
... pulvinar a. Nam gravida euismod magna, non varius justo tincidunt feugiat.
... Aliquam pharetra lacus non risus vehicula rutrum. Maecenas aliquam leo
... felis. Pellentesque semper nunc sit amet nibh ullamcorper, ac elementum
... dolor luctus. Curabitur lacinia mi ornare consectetur vestibulum."""
>>> with bz2.open("myfile.bz2", "wb") as f:
...     # Write compressed data to file
...     unused = f.write(data)
...
>>> with bz2.open("myfile.bz2", "rb") as f:
...     # Decompress data from file
...     content = f.read()
...
>>> content == data  # Check equality to original object after round-trip
True