Ana içeriğe geç

Python’da Zip Dosyalarıyla Çalışma

Bu eğitimde, Python’daki zipfile modülünü kullanarak Zip Dosyalarıyla nasıl çalışacağınızı öğreneceksiniz. zipfile, Python’un yerleşik bir modülüdür.
· 13 dk. oku

Yapay Zeka ile Keşfedin

Zip Dosyalarıyla Çalışmak İçin Ön Koşullar

  • Zip dosya işlemlerini anlamak için Python dosya işlemlerini bilmeniz gerekir. Dosya işlemlerini bilmiyorsanız, öğrenmek için W3Schools’un File Handling bölümüne gidin.
  • Python’da OOP (Nesne Yönelimli Programlama) kavramı
  • Koşullar, döngüler, fonksiyonlar, sınıflar vb. gibi Python kavramları

Kullanacağım tüm Zip klasörlerini indirmek için bu bağlantıyı açın.

Zip Dosyası Nedir?

Zip, kayıpsız veri sıkıştırmayı destekleyen bir arşiv dosya biçimidir. Zip dosyası, bir veya daha fazla sıkıştırılmış dosyayı içeren tek bir dosyadır.

Zip Dosyasının Kullanım Alanları

  • Zip dosyaları, ilgili tüm dosyaları tek bir yerde toplamanıza yardımcı olur.
  • Zip dosyaları veri boyutunu azaltmaya yardımcı olur.
  • Zip dosyaları, birçok bağlantı üzerinden tekil dosyalara göre daha hızlı aktarılır.

zipfile Modülü

zipfile modülünün tüm yöntem ve sınıflarını dir() yöntemiyle keşfedin. zipfile modülünün tüm sınıf ve yöntemlerini almak için koda bakın.

import zipfile # importing the 'zipfile' module

print(dir(zipfile))
['BZIP2_VERSION', 'BadZipFile', 'BadZipfile', 'DEFAULT_VERSION', 'LZMACompressor', 'LZMADecompressor', 'LZMA_VERSION', 'LargeZipFile', 'MAX_EXTRACT_VERSION', 'PyZipFile', 'ZIP64_LIMIT', 'ZIP64_VERSION', 'ZIP_BZIP2', 'ZIP_DEFLATED', 'ZIP_FILECOUNT_LIMIT', 'ZIP_LZMA', 'ZIP_MAX_COMMENT', 'ZIP_STORED', 'ZipExtFile', 'ZipFile', 'ZipInfo', '_CD64_CREATE_VERSION', '_CD64_DIRECTORY_RECSIZE', '_CD64_DIRECTORY_SIZE', '_CD64_DISK_NUMBER', '_CD64_DISK_NUMBER_START', '_CD64_EXTRACT_VERSION', '_CD64_NUMBER_ENTRIES_THIS_DISK', '_CD64_NUMBER_ENTRIES_TOTAL', '_CD64_OFFSET_START_CENTDIR', '_CD64_SIGNATURE', '_CD_COMMENT_LENGTH', '_CD_COMPRESSED_SIZE', '_CD_COMPRESS_TYPE', '_CD_CRC', '_CD_CREATE_SYSTEM', '_CD_CREATE_VERSION', '_CD_DATE', '_CD_DISK_NUMBER_START', '_CD_EXTERNAL_FILE_ATTRIBUTES', '_CD_EXTRACT_SYSTEM', '_CD_EXTRACT_VERSION', '_CD_EXTRA_FIELD_LENGTH', '_CD_FILENAME_LENGTH', '_CD_FLAG_BITS', '_CD_INTERNAL_FILE_ATTRIBUTES', '_CD_LOCAL_HEADER_OFFSET', '_CD_SIGNATURE', '_CD_TIME', '_CD_UNCOMPRESSED_SIZE', '_ECD_COMMENT', '_ECD_COMMENT_SIZE', '_ECD_DISK_NUMBER', '_ECD_DISK_START', '_ECD_ENTRIES_THIS_DISK', '_ECD_ENTRIES_TOTAL', '_ECD_LOCATION', '_ECD_OFFSET', '_ECD_SIGNATURE', '_ECD_SIZE', '_EndRecData', '_EndRecData64', '_FH_COMPRESSED_SIZE', '_FH_COMPRESSION_METHOD', '_FH_CRC', '_FH_EXTRACT_SYSTEM', '_FH_EXTRACT_VERSION', '_FH_EXTRA_FIELD_LENGTH', '_FH_FILENAME_LENGTH', '_FH_GENERAL_PURPOSE_FLAG_BITS', '_FH_LAST_MOD_DATE', '_FH_LAST_MOD_TIME', '_FH_SIGNATURE', '_FH_UNCOMPRESSED_SIZE', '_SharedFile', '_Tellable', '_ZipDecrypter', '_ZipWriteFile', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_check_compression', '_check_zipfile', '_get_compressor', '_get_decompressor', 'binascii', 'bz2', 'compressor_names', 'crc32', 'error', 'importlib', 'io', 'is_zipfile', 'lzma', 'main', 'os', 're', 'shutil', 'sizeCentralDir', 'sizeEndCentDir', 'sizeEndCentDir64', 'sizeEndCentDir64Locator', 'sizeFileHeader', 'stat', 'stringCentralDir', 'stringEndArchive', 'stringEndArchive64', 'stringEndArchive64Locator', 'stringFileHeader', 'struct', 'structCentralDir', 'structEndArchive', 'structEndArchive64', 'structEndArchive64Locator', 'structFileHeader', 'sys', 'threading', 'time', 'zlib']

Bir sürü sınıf ve yöntem gördünüz, değil mi? Ancak hepsini öğrenmeyeceksiniz. Zip dosyalarıyla çalışmak için yalnızca bazı sınıf ve yöntemleri öğreneceksiniz.

Şimdi kısa açıklamalarla bazı yararlı İstisnalar, Sınıflar ve Yöntemlere bakalım.

İstisnalar

İstisna, hatayı istediğiniz gibi tam olarak göstermeye yarayan bir mesajdır. Python’da hata yönetimi için try, except, finally anahtar kelimelerini kullanırsınız.

Hata yönetimine aşina değilseniz, öğrenmek için Python’un Error Handling dokümantasyonuna gidin.

zipfile modülündeki tüm istisnalara bakalım.

zipfile.BadZipFile

zipfile.BadZipFile, zipfile modülündeki bir istisnadır. Bu hata, Bozuk Zip dosyaları için yükseltilir. Aşağıdaki örneğe bakın.

## zipfile.BadZipFile
import zipfile

def main():
    try:
        with zipfile.ZipFile('sample_file.zip') as file: # opening the zip file using 'zipfile.ZipFile' class
            print("Ok")
    except zipfile.BadZipFile: # if the zip file has any errors then it prints the error message which you wrote under the 'except' block
        print('Error: Zip file is corrupted')

if __name__ == '__main__': main()

## I used a badfile for the test
Ok

zipfile.LargeZipFile

Diyelim ki büyük bir Zip dosyasıyla çalışmak istiyorsunuz; Zipi açarken ZIP64 işlevselliğini etkinleştirmeniz gerekir. Bunu etkinleştirmezseniz LargeZipFile istisnası yükselir. Örneğe bakın.

## zipfile.LargeZipFile
## Without enabling 'Zip64'
import zipfile

def main():
    try:
        with zipfile.ZipFile('sample_file.zip') as file:
            print('File size is compatible')
    except zipfile.LargeZipFile: # it raises an 'LargeZipFile' error because you didn't enable the 'Zip64'
        print('Error: File size if too large')

if __name__ == '__main__': main()
File size is compatible
## zipfile.LargeZipFile
## With enabling 'ZIP64'
import zipfile

def main():
    try:
        with zipfile.ZipFile('sample_file.zip', mode = 'r', allowZip64 = True) as file: # here enabling the 'Zip64'
            print('File size is compatible')
    except zipfile.LargeZipFile:
        print('Error: File size if too large') # if the file size is too large to open it prints the error you have written

if __name__ == '__main__': main()
File size is compatible

İstisna yönetimi için en uygun Zip dosyasını seçin ve programı çalıştırmayı deneyin. Net bir fikir edineceksiniz.

Sınıflar

Basitçe söylemek gerekirse, sınıf bir dizi yöntem ve özellikten oluşur. Sınıfın örneklerini oluşturarak sınıf yöntem ve özelliklerini istediğiniz yerde kullanırsınız.

Şimdi zipfile modülünün bazı sınıflarına bakalım.

zipfile.ZipFile

Zip Dosyaları ile çalışmak için en sık kullanılan sınıf ZipFile sınıfıdır.

zipfile.ZipFile, Zip dosyalarını yazmak ve okumak için kullanılır. Zip dosyalarını yönetmek için kullanılan bazı yöntemlere sahiptir.

Şimdi ZipFile sınıfının yöntemlerini dir() nesneleriyle keşfedin. Koda bakın.

import zipfile

print(dir(zipfile.ZipFile)) # accessing the 'ZipFile' class
['_RealGetContents', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_extract_member', '_fpclose', '_open_to_write', '_sanitize_windows_name', '_windows_illegal_name_trans_table', '_write_end_record', '_writecheck', 'close', 'comment', 'extract', 'extractall', 'fp', 'getinfo', 'infolist', 'namelist', 'open', 'printdir', 'read', 'setpassword', 'testzip', 'write', 'writestr']

Önceki örneklerde zipfile.ZipFile sınıfını Zip dosyalarını okumak için zaten kullandınız.

zipfile.ZipFile, Zip dosyalarıyla çalışmak için extract, open, getinfo, setpassword vb. pek çok yöntem içerir.

Şimdi ZipFile sınıfının bazı yöntemlerine bakalım.

## zipfile.ZipFile
import zipfile

def main():
    with zipfile.ZipFile('sample_file.zip') as file:

        # ZipFile.infolist() returns a list containing all the members of an archive file
        print(file.infolist())

        # ZipFile.namelist() returns a list containing all the members with names of an archive file
        print(file.namelist())

        # ZipFile.getinfo(path = filepath) returns the information about a member of Zip file.
        # It raises a KeyError if it doesn't contain the mentioned file
        print(file.getinfo(file.namelist()[-1]))

        # ZipFile.open(path = filepath, mode = mode_type, pwd = password) opens the members of an archive file
        # 'pwd' is optional -> if it has password mention otherwise leave it
        text_file = file.open(name = file.namelist()[-1], mode = 'r')

        # 'read()' method of the file prints all the content of the file. You see this method in file handling.
        print(text_file.read())  

        # You must close the file if you don't open a file using 'with' keyword
        # 'close()' method is used to close the file
        text_file.close()

        # ZipFile.extractall(path = filepath, pwd = password) extracts all the files to current directory
        file.extractall()
        # after executing check the directory to see extracted files


if __name__ == '__main__': main()
[<ZipInfo filename='extra_file.txt' filemode='-rw-rw-rw-' file_size=59>, <ZipInfo filename='READ ME.txt' filemode='-rw-rw-rw-' file_size=59>, <ZipInfo filename='even_odd.py' filemode='-rw-rw-rw-' file_size=129>]
['extra_file.txt', 'READ ME.txt', 'even_odd.py']
<ZipInfo filename='even_odd.py' filemode='-rw-rw-rw-' file_size=129>
b"num = int(input('Enter a Number:- '))\r\nif num % 2 == 0:\r\n\tprint('{} is Even'.fromat(num))\r\nelse:\r\n\tprint('{} is Odd'.fromat(num))"

ZipFile sınıfının tüm yöntemlerini öğrenmek istiyorsanız, öğrenmek istediğiniz yöntem üzerinde help() fonksiyonunu kullanın.

Ya da öğrenmek için Python’un resmi dokümantasyonuna gidin.

zipfile.ZipInfo

zipfile.ZipInfo sınıfı, bir Zip klasörünün üyesini temsil etmek için kullanılır.

Önce, dir() yöntemiyle zipfile.ZipInfo sınıfının tüm nesnelerini keşfedin. Aşağıdaki koda bakın.

## zipfile.ZipInfo
import zipfile

print(dir(zipfile.ZipInfo))
['CRC', 'FileHeader', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '_decodeExtra', '_encodeFilenameFlags', '_raw_time', 'comment', 'compress_size', 'compress_type', 'create_system', 'create_version', 'date_time', 'external_attr', 'extra', 'extract_version', 'file_size', 'filename', 'flag_bits', 'from_file', 'header_offset', 'internal_attr', 'is_dir', 'orig_filename', 'reserved', 'volume']

Şimdi zipfile.ZipInfo sınıfının bazı yöntemlerini göreceksiniz

## zipfile.ZipInfo
import zipfile

def main():
    with zipfile.ZipFile('sample_file.zip') as file:

        # 'infolist()' is the object of 'ZipFile' class
        # 'infolist()' returns a list containing all the folders and files of the zip -> 'ZipInfo' objects
        # assigning last element of the list to a variable to test all the methods of 'ZipInfo'
        archive = file.infolist()
        read_me_file = archive[-1]

        # 'ZipInfo' methods

        # ZipInfo_object.filename returns the name of the file
        print("Name of the file:- {}".format(read_me_file.filename))

        # ZipInfo_object.file_size returns the size of the file
        print("Size of the file:- {}".format(read_me_file.file_size))

        # ZipInfo_object.is_dir() returns True if it's directory otherwise False
        print("Is directory:- {}".format(read_me_file.is_dir()))

        # ZipInfo_object.date_time() returns the created date & time of file
        print("File created data & time:- {}".format(read_me_file.date_time))

if __name__ == '__main__': main()
Name of the file:- sample_file/READ ME.txt
Size of the file:- 59
Is directory:- False
File created data & time:- (2018, 10, 4, 11, 32, 22)

ZipInfo nesneleri hakkında daha fazla öğrenmek istiyorsanız ZipInfo’ya gidin.

Yöntemler

Yöntemler, programda belirli bir işlevsellik için yazılmış kod bloklarıdır. Örneğin, bir sayının mutlak değerini bulmak istiyorsanız, Python’daki abs adlı yöntemi kullanabilirsiniz.

İstediğiniz yerde kullanabilirsiniz. Şimdi zipfile modülünün bazı yöntemlerine bakalım.

zipfile.is_zipfile()

zipfile modülünün is_zipfile(filename) yöntemi, dosya geçerli bir Zip ise True, değilse False döndürür.

Bir örneğe bakalım.

## zipfile.is_zip(filename)
import zipfile

def main():
    print(zipfile.is_zipfile('sample_file.zip')) # it returns True

if __name__ == '__main__': main()
True

Zip Dosyalarını Yönetme

Bu bölümde Zip dosyalarını Açma, Çıkarma, Yazma vb. işlemlerini nasıl yapacağınızı öğreneceksiniz.

Bir Zip Dosyasını Çıkarmak

Bir Zip dosyasının içindeki dosyaları extractall yöntemiyle geçerli dizine çıkarın.

## extracting zip file
import zipfile

def main():

    # assigning filename to a variable
    file_name = 'sample_file.zip'

    # opening Zip using 'with' keyword in read mode
    with zipfile.ZipFile(file_name, 'r') as file:
        # printing all the information of archive file contents using 'printdir' method
        print(file.printdir())

        # extracting the files using 'extracall' method
        print('Extracting all files...')
        file.extractall()
        print('Done!') # check your directory of zip file to see the extracted files

if __name__ == '__main__': main()
File Name                                             Modified             Size
sample_file/                                   2018-10-04 11:33:22            0
sample_file/even_odd.py                        2018-06-29 23:35:54          129
sample_file/READ ME.txt                        2018-10-04 11:32:22           59
None
Extracting all files...
Done!

Parolalı Bir Zip’i Çıkarmak

Parolalı bir Zipi çıkarmak için, extract(pwd = password) veya extractall(pwd = password) yöntemlerinin pwd konumsal bağımsız değişkenine bir değer geçirmeniz gerekir.

Geçirdiğiniz parola byte türünde olmalıdır. Bir str’ı byte’a dönüştürmek için utf-8 kodlama biçimiyle Python’un yerleşik bytes yöntemini kullanın.

Bir örneğe bakalım.

## extracting zip with password
import zipfile

def main():
    file_name = 'pswd_file.zip'
    pswd = 'datacamp'

    with zipfile.ZipFile(file_name) as file:
        # password you pass must be in the bytes you converted 'str' into 'bytes'
        file.extractall(pwd = bytes(pswd, 'utf-8'))

if __name__ == '__main__': main()

Ayrıca ZipFile sınıfının setpassword(pwd = password) yöntemini kullanarak da dosyaları çıkarabilirsiniz. Aşağıdaki örneğe bakın.

## extracting zip with password
import zipfile

def main():
    file_name = 'pswd_file.zip'
    pswd = 'datacamp'

    with zipfile.ZipFile(file_name) as file:
        # 'setpassword' method is used to give a password to the 'Zip'
        file.setpassword(pwd = bytes(pswd, 'utf-8'))
        file.extractall()

if __name__ == '__main__': main()

Zip Dosyaları Oluşturma

Bir Zip dosyası oluşturmak için ekstra bir yönteme ihtiyacınız yok. ZipFile sınıfına adı verin, o da geçerli dizinde bir arşiv oluşturacaktır.

Aşağıdaki örneğe bakın.

## Creating Zip file
import zipfile

def main():

    archive_name = 'example_file.zip'
    # below one line of code will create a 'Zip' in the current working directory
    with zipfile.ZipFile(archive_name, 'w') as file:
        print("{} is created.".format(archive_name))

if __name__ == '__main__': main()
example_file.zip is created.

Zip Dosyalarına Yazma

Dosyaları arşiv dosyasına yazmak için Zip dosyalarını yazma modunda açmalısınız. Bu, Zip’teki mevcut tüm dosyaların üzerine yazar.

Bir örnek görelim.

## Writing files to zip
import zipfile

def main():

    file_name = 'sample_file.zip'

    # Opening the 'Zip' in writing mode
    with zipfile.ZipFile(file_name, 'w') as file:
        # write mode overrides all the existing files in the 'Zip.'
        # you have to create the file which you have to write to the 'Zip.'
        file.write('extra_file.txt')
        print('File overrides the existing files')

    # opening the 'Zip' in reading mode to check
    with zipfile.ZipFile(file_name, 'r') as file:
        print(file.namelist())

if __name__ == '__main__': main()
File overrides the existing files
['extra_file.txt']

Zip’e Dosya Ekleme

Herhangi bir dosyayı Zipe eklemek için append (a) modunda açmalısınız. Mevcut dosyaların üzerine yazmaz.

Bir örnek görelim.

## Appending files to zip
import zipfile

def main():

    file_name = 'sample_file.zip'

    # opening the 'Zip' in writing mode
    with zipfile.ZipFile(file_name, 'a') as file:
        # append mode adds files to the 'Zip'
        # you have to create the files which you have to add to the 'Zip'
        file.write('READ ME.txt')
        file.write('even_odd.py')
        print('Files added to the Zip')

    # opening the 'Zip' in reading mode to check
    with zipfile.ZipFile(file_name, 'r') as file:
        print(file.namelist())

if __name__ == '__main__': main()
Files added to the Zip
['extra_file.txt', 'READ ME.txt', 'even_odd.py']

Buraya kadar Zip dosyalarının nasıl yönetileceğini öğrendiniz. Artık Zip dosyalarını açabilir, yazabilir, ekleyebilir, çıkarabilir, oluşturabilir vb. işlemleri yapabilirsiniz. Şimdi basit bir program yazacaksınız.

Bakın, neymiş?

Döngüler ve zipfile Kullanarak Parolalı Birden Çok Alt Zip’i Çıkarmak

  • Elinizde derinlikte bazı alt Zip dosyaları içeren bir Zip var. Ve her Zip dosyasının parolası kendi adı. Amacımız, sona ulaşana kadar tüm Zipleri açmak.

Problemi Çözme Adımları

  • Üst Dosyayı, adı parolası olacak şekilde çıkarın.
  • namelist() yöntemiyle ilk alt öğenin adını alın. Bir değişkende saklayın.
  • Sonsuz Kez döngüyü çalıştırın.

    • Dosyanın Zip olup olmadığını is_zipfile() yöntemiyle kontrol edin. Eğer öyleyse şunları yapın.

      • name değişkeniyle zip’i açın.

      • Zipin parolasını name değişkeninden alın.

      • Zipi çıkarın.

      • Bir sonraki Zip adını alın ve name değişkeninde saklayın.

    • aksi halde

      • break kullanarak döngüyü kırın.

Yukarıdaki Prosedürü ben oluşturdum. İsterseniz dosyalarınızın düzenine göre değiştirebilirsiniz.

## Solution
import zipfile

def main():

    # storing the parent name
    parent_file_name = '000.zip'

    with zipfile.ZipFile(parent_file_name, 'r') as parent_file:

        # extracting the parent file
        pswd = bytes(parent_file_name.split('.')[0], 'utf-8')
        parent_file.extractall(pwd = pswd)

        # getting the first child
        next_zip_name = parent_file.namelist()[0]

        # looping through the sub zips infinite times until you don't encouter a 'Zip' file
        while True:

            if zipfile.is_zipfile(next_zip_name):
                # opening the zip
                with zipfile.ZipFile(next_zip_name, 'r') as child_file:

                    # getting password from the zip name
                    pswd = bytes(next_zip_name.split('.')[0], 'utf-8')

                    # extracting the zip
                    child_file.extractall(pwd = pswd)

                    # getting the child zip name
                    next_zip_name = child_file.namelist()[0]
            else:
                break

if __name__ == '__main__': main()

Yukarıdaki programı çalıştırdıktan sonra, tüm alt ziplerin geçerli dizine çıkarıldığını göreceksiniz.

Son Not

Tebrikler, eğitimi tamamladınız!

Umarım eğitim hoşunuza gitmiştir. Bu makale, Zip dosyalarıyla çalışırken size epey yardımcı olacaktır. Artık Zip dosyalarıyla çalışabilirsiniz.

Makale ile ilgili herhangi bir sorunuz varsa, yorum bölümünde sorun. En kısa sürede yanıtlayacağım.

Yine, Python’a yeniyseniz, Python dilini öğrenmek için DataCamp’in ücretsiz Intro to Python for Data Science kursunu alın ya da Python’ın resmi dokümantasyonunu okuyun.

Keyifli Kodlamalar!

Konular

İlgili