وبلاگ رسانگار
با ما حرفه ای باشید

سرور مجازی NVMe

ایجاد یک آرشیو فشرده از یک فهرست در پایتون

0 36
زمان لازم برای مطالعه: 7 دقیقه


معرفی

هنگامی که با حجم زیادی از داده ها یا فایل ها سروکار دارید، ممکن است نیاز داشته باشید که فایل ها را در قالبی قابل مدیریت تر فشرده کنید. یکی از بهترین راه ها برای انجام این کار، ایجاد یک آرشیو فشرده است.

در این مقاله، نحوه ایجاد یک آرشیو فشرده از یک دایرکتوری با استفاده از پایتون را بررسی خواهیم کرد. چه به دنبال صرفه‌جویی در فضا، ساده‌سازی اشتراک‌گذاری فایل یا سازماندهی چیزها هستید، پایتون zipfile ماژول برای انجام این کار ارائه می دهد.

ایجاد یک آرشیو فشرده با پایتون

کتابخانه استاندارد پایتون با ماژولی به نام ارائه می شود zipfile که روش هایی را برای ایجاد، خواندن، نوشتن، الحاق و فهرست بندی محتویات یک فایل ZIP ارائه می دهد. این ماژول برای ایجاد یک آرشیو فشرده از یک فهرست مفید است. ما با وارد کردن شروع می کنیم zipfile و os ماژول ها:

import zipfile
import os

حالا بیایید یک تابع ایجاد کنیم که یک دایرکتوری را فشرده کند:

def zip_directory(directory_path, zip_path):
    with zipfile.ZipFile(zip_path, 'w') as zipf:
        for root, dirs, files in os.walk(directory_path):
            for file in files:
                zipf.write(os.path.join(root, file), 
                           os.path.relpath(os.path.join(root, file), 
                                           os.path.join(directory_path, '..')))

در این تابع ابتدا یک فایل فشرده جدید را در حالت نوشتن باز می کنیم. سپس، از طریق دایرکتوری که می خواهیم زیپ کنیم عبور می کنیم. برای هر فایل در دایرکتوری، از write() روش اضافه کردن آن به فایل فشرده این os.path.relpath() از تابع استفاده می شود تا مسیر نسبی فایل را به جای مسیر مطلق در فایل zip ذخیره کنیم.

بیایید عملکرد خود را آزمایش کنیم:

zip_directory('test_directory', 'archive.zip')

پس از اجرای این کد، باید یک فایل جدید با نام مشاهده کنید archive.zip در فهرست فعلی شما این فایل زیپ شامل تمام فایل های از test_directory.

توجه داشته باشید: در تعیین مسیرها دقت کنید. اگر zip_path فایل از قبل وجود دارد، بازنویسی خواهد شد.

پایتون zipfile ماژول ایجاد یک آرشیو فشرده از یک فهرست را آسان می کند. تنها با چند خط کد، می توانید فایل های خود را فشرده و سازماندهی کنید.

در بخش‌های بعدی، بیشتر به مدیریت دایرکتوری‌های تودرتو، دایرکتوری‌های بزرگ و مدیریت خطا خواهیم پرداخت. ممکن است کمی عقب‌تر به نظر برسد، اما عملکرد بالا احتمالاً همان چیزی است که بیشتر مردم برای آن به اینجا آمده‌اند، بنابراین می‌خواستم ابتدا آن را نشان دهم.

با استفاده از ماژول zipfile

در پایتون، zipfile ماژول بهترین ابزار برای کار با آرشیوهای فشرده است. این توابع برای خواندن، نوشتن، الحاق و استخراج داده ها از فایل های فشرده ارائه می دهد. ماژول بخشی از کتابخانه استاندارد پایتون است، بنابراین نیازی به نصب هیچ چیز اضافی نیست.

در اینجا یک مثال ساده از نحوه ایجاد یک فایل فشرده جدید و اضافه کردن یک فایل به آن آورده شده است:

import zipfile


zip_file = zipfile.ZipFile('example.zip', 'w')


zip_file.write('test.txt')


zip_file.close()

در این کد ابتدا کد را وارد می کنیم zipfile مدول. سپس، یک فایل فشرده جدید به نام ‘example.zip’ در حالت نوشتن (‘w’) ایجاد می کنیم. ما یک فایل به نام “test.txt” را با استفاده از فایل فشرده به فایل فشرده اضافه می کنیم write() روش. در نهایت فایل فشرده را با استفاده از close() روش.

ایجاد یک آرشیو فشرده از یک دایرکتوری

ایجاد یک آرشیو فشرده از یک دایرکتوری کمی کار بیشتری را شامل می شود، اما هنوز هم با zipfile مدول. شما باید در ساختار دایرکتوری قدم بزنید و هر فایل را به آرشیو فشرده اضافه کنید.

import os
import zipfile

def zip_directory(folder_path, zip_file):
    for folder_name, subfolders, filenames in os.walk(folder_path):
        for filename in filenames:
            
            file_path = os.path.join(folder_name, filename)
            
            zip_file.write(file_path)


zip_file = zipfile.ZipFile('example_directory.zip', 'w')


zip_directory('/path/to/directory', zip_file)


zip_file.close()

ابتدا یک تابع تعریف می کنیم zip_directory() که مسیر پوشه ای را می گیرد و الف ZipFile هدف – شی. از os.walk() عملکردی برای تکرار روی همه فایل های دایرکتوری و زیر شاخه های آن. برای هر فایل، مسیر کامل فایل را می سازد و فایل را به آرشیو فشرده اضافه می کند.

پیشنهاد می‌کنیم بخوانید:  جاوا اسکریپت: بررسی کنید که آیا یک شی EmptyObjects برای ذخیره مجموعه ای از ویژگی ها استفاده می شود، که هر کدام ممکن است به عنوان ارتباطی بین یک نام (یا کلید) و یک مقدار (مجموعه ای از جفت های کلید-مقدار) در نظر گرفته شوند. در این راهنما، بسیاری از روش های جاوا اسکریپت را بررسی خواهیم کرد روی چگونه بررسی کنیم که آیا یک شی خالی است ....

این os.walk() تابع یک راه راحت برای عبور از دایرکتوری ها است. نام فایل ها را در درخت دایرکتوری با راه رفتن درخت از بالا به پایین یا پایین به بالا تولید می کند.

توجه داشته باشید: هنگام افزودن فایل ها به آرشیو zip مراقب مسیرهای فایل باشید. این write() متد فایل ها را با مسیر دقیقی که شما ارائه می دهید به آرشیو اضافه می کند. اگر یک مسیر مطلق ارائه کنید، فایل با مسیر مطلق کامل در بایگانی فشرده اضافه می شود. معمولاً این چیزی نیست که شما می خواهید. در عوض، شما معمولاً می خواهید فایل هایی با یک مسیر نسبی به دایرکتوری که در حال فشرده سازی هستید اضافه کنید.

در قسمت اصلی اسکریپت، یک فایل zip جدید ایجاد می کنیم که با آن تماس بگیرید zip_directory() برای اضافه کردن دایرکتوری به فایل فشرده و در نهایت بستن فایل فشرده.

کار با دایرکتوری های تودرتو

هنگام کار با دایرکتوری های تو در تو، فرآیند ایجاد یک آرشیو فشرده کمی پیچیده تر است. اولین تابعی که در این مقاله نشان دادیم در واقع این مورد را نیز کنترل می کند، که دوباره در اینجا نشان خواهیم داد:

import os
import zipfile

def zipdir(path, ziph):
    for root, dirs, files in os.walk(path):
        for file in files:
            ziph.write(os.path.join(root, file), 
                       os.path.relpath(os.path.join(root, file), 
                                       os.path.join(path, '..')))
            
zipf = zipfile.ZipFile('Python.zip', 'w', zipfile.ZIP_DEFLATED)
zipdir('/path/to/directory', zipf)
zipf.close()

تفاوت اصلی این است که ما در واقع پوشه فشرده را خارج از تابع ایجاد می کنیم و آن را به عنوان یک پارامتر ارسال می کنیم. اینکه آیا این کار را در خود عملکرد انجام دهید یا نه، به اولویت شخصی بستگی دارد.

مدیریت دایرکتوری های بزرگ

پس اگر با یک دایرکتوری بزرگ سر و کار داشته باشیم چه؟ زیپ کردن یک دایرکتوری بزرگ می تواند حافظه زیادی را مصرف کند و حتی اگر اقدامات احتیاطی درست را انجام ندهید، برنامه شما را خراب کند.

خوشبختانه، zipfile ماژول به ما اجازه می دهد تا یک آرشیو فشرده ایجاد کنیم بدون بارگیری همه فایل ها به یکباره در حافظه با استفاده از with بیانیه، ما می توانیم اطمینان حاصل کنیم که هر فایل پس از اضافه شدن به آرشیو بسته شده و حافظه آن آزاد می شود.

import os
import zipfile

def zipdir(path, ziph):
    for root, dirs, files in os.walk(path):
        for file in files:
            with open(os.path.join(root, file), 'r') as fp:
                ziph.write(fp.read())

with zipfile.ZipFile('Python.zip', 'w', zipfile.ZIP_DEFLATED) as zipf:
    zipdir('/path/to/directory', zipf)

در این نسخه، ما از with بیانیه هنگام باز کردن هر فایل و هنگام ایجاد آرشیو فشرده. این تضمین می کند که هر فایل پس از خواندن بسته می شود و حافظه ای را که استفاده می کرد آزاد می کند. به این ترتیب، می‌توانیم با خیال راحت دایرکتوری‌های بزرگ را بدون مشکل حافظه زیپ کنیم.

مدیریت خطا در فایل فشرده

هنگام کار با zipfile در پایتون، باید به یاد داشته باشیم که استثناها را مدیریت کنیم تا برنامه ما به طور غیرمنتظره خراب نشود. متداول ترین استثناهایی که ممکن است با آن مواجه شوید هستند RuntimeError، ValueError، و FileNotFoundError.

بیایید نگاهی بیندازیم که چگونه می‌توانیم این استثناها را هنگام ایجاد یک فایل فشرده مدیریت کنیم:

import zipfile

try:
    with zipfile.ZipFile('example.zip', 'w') as myzip:
        myzip.write('non_existent_file.txt')
except FileNotFoundError:
    print('The file you are trying to zip does not exist.')
except RuntimeError as e:
    print('An unexpected error occurred:', str(e))
except zipfile.LargeZipFile:
    print('The file is too large to be compressed.')

FileNotFoundError زمانی که فایلی که می‌خواهیم زیپ کنیم وجود نداشته باشد بالا می‌رود. RuntimeError یک استثنا کلی است که ممکن است به دلایلی مطرح شود، بنابراین ما پیام استثنا را چاپ می کنیم تا بفهمیم چه مشکلی رخ داده است. zipfile.LargeZipFile زمانی که فایلی که می‌خواهیم فشرده کنیم خیلی بزرگ باشد بالا می‌رود.

توجه داشته باشید: پایتون zipfile ماژول a را بالا می برد LargeZipFile وقتی فایلی که می‌خواهید فشرده کنید بزرگ‌تر از 2 گیگابایت باشد، خطا رخ می‌دهد. اگر با فایل های حجیم کار می کنید، می توانید با تماس از این خطا جلوگیری کنید ZipFile با allowZip64=True بحث و جدل.

پیشنهاد می‌کنیم بخوانید:  آموزش PyGame – چگونه یک بازی Alien Abduction بسازیم

خطاهای رایج و راه حل ها

در حین کار با zipfile ماژول، ممکن است با چندین خطای رایج روبرو شوید. بیایید برخی از این خطاها و راه حل های آنها را بررسی کنیم:

FileNotFoundError

این خطا زمانی رخ می دهد که فایل یا دایرکتوری که می خواهید فشرده سازی کنید وجود نداشته باشد. بنابراین همیشه قبل از اقدام به فشرده سازی فایل یا دایرکتوری موجود بودن آن را بررسی کنید.

IsADirectoryError

این خطا زمانی ایجاد می‌شود که می‌خواهید یک دایرکتوری را با استفاده از فایل فشرده بنویسید ZipFile.write(). برای جلوگیری از این، استفاده کنید os.walk() برای عبور از دایرکتوری و نوشتن فایل های فردی بجای.

خطای مجوز

همانطور که احتمالاً حدس زده اید، این خطا زمانی رخ می دهد که شما مجوزهای لازم برای خواندن فایل یا نوشتن در فهرست را ندارید. قبل از دستکاری فایل ها یا دایرکتوری ها مطمئن شوید که مجوزهای صحیح را دارید.

فایل زیپ بزرگ

همانطور که قبلا ذکر شد، این خطا زمانی ایجاد می شود که فایلی که می خواهید فشرده کنید بزرگتر از 2 گیگابایت باشد. برای جلوگیری از این خطا تماس بگیرید ZipFile با allowZip64=True بحث و جدل.

try:
    with zipfile.ZipFile('large_file.zip', 'w', allowZip64=True) as myzip:
        myzip.write('large_file.txt')
except zipfile.LargeZipFile:
    print('The file is too large to be compressed.')

در این قطعه، ما از allowZip64=True آرگومان برای اجازه زیپ فایل های بزرگتر از 2 گیگابایت.

فشرده سازی فایل های فردی

با zipfile، نه تنها می تواند دایرکتوری ها را فشرده کند، بلکه می تواند فایل های فردی را نیز فشرده کند. فرض کنید فایلی به نام دارید document.txt که می خواهید فشرده کنید. در اینجا نحوه انجام این کار به شرح زیر است:

import zipfile

with zipfile.ZipFile('compressed_file.zip', 'w') as myzip:
    myzip.write('document.txt')

در این کد، یک آرشیو فشرده جدید به نام ایجاد می کنیم compressed_file.zip و فقط اضافه کردن document.txt به آن پارامتر “w” به این معنی است که ما فایل فشرده را در حالت نوشتن باز می کنیم.

اکنون، اگر دایرکتوری خود را بررسی کنید، باید یک فایل فشرده جدید با نام مشاهده کنید compressed_file.zip.

و در نهایت، بیایید ببینیم که چگونه می توان این زیپ را با استخراج فایل ها معکوس کرد. فرض کنید می خواهیم آن را استخراج کنیم document.txt فایلی که فقط فشرده کردیم در اینجا نحوه انجام آن آمده است:

import zipfile

with zipfile.ZipFile('compressed_file.zip', 'r') as myzip:
    myzip.extractall()

در این قطعه کد، فایل فشرده را در حالت خواندن (‘r’) باز می کنیم و سپس extractall() روش. این روش تمام فایل های موجود در بایگانی zip را به دایرکتوری فعلی استخراج می کند.

توجه داشته باشید: اگر می‌خواهید فایل‌ها را در یک دایرکتوری خاص استخراج کنید، می‌توانید مسیر دایرکتوری را به عنوان آرگومان به آن ارسال کنید extractall() روشی مثل این: myzip.extractall('/path/to/directory/').

حالا، اگر دایرکتوری خود را بررسی کنید، باید آن را ببینید document.txt فایل. این تمام چیزی است که وجود دارد!

نتیجه

در این راهنما، ما بر ایجاد و مدیریت آرشیوهای فشرده در پایتون تمرکز کردیم. را بررسی کردیم zipfile ماژول، یاد گرفت که چگونه یک بایگانی فشرده از یک دایرکتوری ایجاد کند، و حتی در مدیریت دایرکتوری های تودرتو و دایرکتوری های بزرگ وارد عمل شد. ما همچنین مدیریت خطا در فایل فشرده، خطاهای رایج و راه حل های آنها، فشرده سازی فایل های فردی و استخراج فایل های فشرده را پوشش داده ایم.





منتشر شده در 1402-12-27 05:00:05

امتیاز شما به این مطلب
دیدگاه شما در خصوص مطلب چیست ؟

آدرس ایمیل شما منتشر نخواهد شد.

لطفا دیدگاه خود را با احترام به دیدگاه های دیگران و با توجه به محتوای مطلب درج کنید