zipfile do kompresji i dekompresji plików ZIP w Pythonie

Biznes

Moduł zipfile standardowej biblioteki Pythona może być używany do kompresji plików do formatu ZIP i rozpakowywania plików ZIP. Jest on zawarty w bibliotece standardowej, więc nie jest wymagana dodatkowa instalacja.

Objaśnione są następujące treści.

  • Kompresja wielu plików do pliku ZIP
  • Dodaj nowy plik do istniejącego pliku ZIP
  • Kompresja katalogu (folderu) do pliku ZIP
  • Skompresowane do pliku ZIP z hasłem
  • Sprawdź zawartość pliku ZIP.
  • Wyodrębnij (rozpakuj) całą zawartość pliku ZIP.
  • Wybierz zawartość pliku ZIP i rozpakuj go.

Kompresja wielu plików do pliku ZIP

Utwórz obiekt ZipFile i użyj metody write() aby dodać pliki, które chcesz skompresować.

Aby utworzyć nowy plik ZIP, jako pierwszy argument konstruktora obiektu ZipFile należy podać ścieżkę do tworzonego pliku ZIP, a drugi argument w następujący sposób'w'

Dodatkowo, jako trzeci argument można podać metodę kompresji.

  • zipfile.ZIP_STORED:Po prostu połącz wiele plików bez kompresji (domyślnie)
  • zipfile.ZIP_DEFLATED:Normalna kompresja ZIP (wymagany moduł zlib)
  • zipfile.ZIP_BZIP2:Kompresja BZIP2 (wymagany moduł bz2)
  • zipfile.ZIP_LZMA:Kompresja LZMA (wymagany moduł lzma)

BZIP2 i LZMA mają wyższy stopień kompresji (mogą być skompresowane do mniejszego rozmiaru), ale czas wymagany do kompresji jest dłuższy.

W metodzie write(), plik z pierwszym argumentem filename jest zapisywany do pliku ZIP z drugim argumentem arcname. Jeśli pominięto arcname, nazwa pliku jest używana taka, jaka jest. arcname może również określać strukturę katalogów.

Obiekt ZipFile musi zostać zamknięty za pomocą metody close(), ale jeśli użyjesz instrukcji with, zostanie on zamknięty automatycznie po zakończeniu bloku.

import zipfile

with zipfile.ZipFile('data/temp/new_comp.zip', 'w', compression=zipfile.ZIP_DEFLATED) as new_zip:
    new_zip.write('data/temp/test1.txt', arcname='test1.txt')
    new_zip.write('data/temp/test2.txt', arcname='zipdir/test2.txt')
    new_zip.write('data/temp/test3.txt', arcname='zipdir/sub_dir/test3.txt')

Poprzez określenie argumentu compress_type metody write(), możliwe jest również wybranie metody kompresji dla każdego pliku.

with zipfile.ZipFile('data/temp/new_comp_single.zip', 'w') as new_zip:
    new_zip.write('data/temp/test1.txt', arcname='test1.txt', compress_type=zipfile.ZIP_DEFLATED)
    new_zip.write('data/temp/test2.txt', arcname='zipdir/test2.txt')
    new_zip.write('data/temp/test3.txt', arcname='zipdir/sub_dir/test3.txt')

Dodaj nowy plik do istniejącego pliku ZIP

W celu dodania nowego pliku do istniejącego pliku zip należy przy wytworzeniu obiektu ZipFile ustawić pierwszy argument konstruktora na ścieżkę do istniejącego pliku zip. Również drugi argument ustawić w następujący sposób.'a'

Następnie, tak jak w powyższym przykładzie, po prostu dodaj plik używając metody write().

with zipfile.ZipFile('data/temp/new_comp.zip', 'a') as existing_zip:
    existing_zip.write('data/temp/test4.txt', arcname='test4.txt')

Kompresja katalogu (folderu) do pliku ZIP

Jeśli chcesz skompresować cały katalog (folder) do pojedynczego pliku ZIP, możesz użyć os.scandir() lub os.listdir() do zrobienia listy plików, ale łatwiej jest użyć make_archive() w module shutil.

Zobacz następujący artykuł.

Skompresowane do pliku ZIP z hasłem

Moduł zipfile nie pozwala na tworzenie chronionych hasłem plików ZIP. Jeśli chcesz skompresować plik do chronionego hasłem pliku zip, użyj biblioteki trzeciej strony pyminizip.

Zauważ, że dekompresja ZIP-ów chronionych hasłem może być wykonana za pomocą modułu zipfile (zobacz poniżej).

Sprawdź zawartość pliku ZIP.

Można sprawdzić zawartość istniejącego pliku ZIP.

Tworzy obiekt ZipFile przez ustawienie pierwszego argumentu file w konstruktorze na ścieżkę do istniejącego pliku zip i drugiego argumentu mode na 'r'. Argument mode może zostać pominięty, ponieważ domyślnie jest to 'r'.

Możesz użyć metody namelist() obiektu ZipFile, aby uzyskać listę zarchiwizowanych plików.

with zipfile.ZipFile('data/temp/new_comp.zip') as existing_zip:
    print(existing_zip.namelist())
# ['test1.txt', 'zipdir/test2.txt', 'zipdir/sub_dir/test3.txt', 'test4.txt']

Wyodrębnij (rozpakuj) całą zawartość pliku ZIP.

Aby rozpakować zawartość pliku ZIP, utwórz obiekt ZipFile z pierwszym argumentem file w konstruktorze jako ścieżką do istniejącego pliku ZIP i drugim argumentem mode jako 'r', jak w powyższym przykładzie. Argument mode może być pominięty, ponieważ domyślnie przyjmuje wartość 'r'.

Metoda extractall() obiektu ZipFile wyodrębnia (dekompresuje) całą zawartość pliku ZIP. Pierwszy argument, ścieżka, określa ścieżkę katalogu, do którego ma zostać rozpakowana zawartość. Jeżeli zostanie pominięty, pliki zostaną rozpakowane do bieżącego katalogu.

with zipfile.ZipFile('data/temp/new_comp.zip') as existing_zip:
    existing_zip.extractall('data/temp/ext')

Plik ZIP z hasłem może zostać wyodrębniony przez podanie hasła jako argumentu pwd metody extractall().

with zipfile.ZipFile('data/temp/new_comp_with_pass.zip') as pass_zip:
    pass_zip.extractall('data/temp/ext_pass', pwd='password')

Wybierz zawartość pliku ZIP i rozpakuj go.

Jeśli chcesz rozpakować i rozpakować tylko niektóre pliki, użyj metody extract().

Pierwszym argumentem metody extract() jest nazwa pliku do wyodrębnienia, a drugim argument path jest ścieżka katalogu, do którego ma zostać wyodrębniony plik. Jeśli argument ścieżka zostanie pominięty, plik zostanie wyodrębniony do bieżącego katalogu. Nazwa pliku do rozpakowania powinna zawierać ścieżkę do katalogu w pliku ZIP, jeśli jest on tam zapisany.

with zipfile.ZipFile('data/temp/new_comp.zip') as existing_zip:
    existing_zip.extract('test1.txt', 'data/temp/ext2')

Podobnie jak metoda extractall(), metoda extract() również pozwala na podanie hasła jako argumentu pwd.

with zipfile.ZipFile('data/temp/new_comp_with_pass.zip') as pass_zip:
    pass_zip.extract('test1.txt', 'data/temp/ext_pass2', pwd='password')