Что такое ZIP-архив?
ZIP - это формат архива, который используется для сжатия и хранения данных. Он позволяет объединить несколько файлов в один и при этом уменьшить их общий размер за счет алгоритмов сжатия. Например, DEFLATE. Это позволяет удобно передавать и хранить данные.
Основные особенности которые можно выделить:
- поддерживает разные методы сжатия
- можно поставить пароль для защиты
- широко используется во многих операционках
Зачем использовать zipfile?
zipfile - это встроенный модуль в Python. Он предназначен для работы с zip-архивами. Давай посмотрим на преимущества его:
- встроенность - не надо ничего дополнительно скачивать и жмякать в этих ваших интернетах
- простота использования
- автоматизация задач - можно написать скрипт, который будет собирать файлы в архив или наоборот распаковывать
Основные концепции работы с zip-архивами
Архив - это единый файл, в котором содержится один или несколько сжатых файлов. Каждый файл внутри архива может иметь собственную степень сжатия и метаданные.
Методы сжатия
- ZIP_STORED - без сжатия
- ZIP_DEFLATED - стандартный метод (DEFLATE)
- ZIP_BZIP2 - сжатие с использованием ZIP_BZIP2
- ZIP_LZMA - сжатие с использованием ZIP_LZMA
Для использования методов необходимо установить модуль zlib.
Базовые операции с zipfile
Создание архива
Для создания нового архива используй класс ZipFile с режимом "w":
import zipfile
with zipfile.ZipFile('example.zip', 'w', compression=zipfile.ZIP_DEFLATED) as zipf:
zipf.write('file1.txt')
zipf.write('file2.txt')
Чтение содержимого
Чтобы посмотреть что внутри находится надо сделать следующее:
with zipfile.ZipFile('example.zip', 'r') as zipf:
print(zipf.namelist())
Это выведет список файлов.
Извлечение файлов из архива
Ну давай теперь распакуем файлики:
with zipfile.ZipFile('example.zip', 'r') as zipf:
zipf.extractall('output_directory')
Ты хочешь конкретный файл получить? Пожалуйста:
with zipfile.ZipFile('example.zip', 'r') as zipf:
zipf.extract('file1.txt', 'output_directory')
Добавляем файлы в созданный архив
Для этого откроем нашего красавчика в режиме "a":
with zipfile.ZipFile('example.zip', 'a', compression=zipfile.ZIP_DEFLATED) as zipf:
zipf.write('new_file.txt')
Проверка целостности
Ну и конечно нужно проверить все ли хорошо.
with zipfile.ZipFile('example.zip', 'r') as zipf:
bad_file = zipf.testzip()
if bad_file:
print(f"Ошибка в файле: {bad_file}")
else:
print("Архив целостный")
Расширенные возможности
Ну что ты, киборг-убийца? Готов узнать еще больше? Давай посмотрим чуть шире и потренируем извилину дополнительно.
Работа с директориями
Если есть файлы, то есть и директории с файлами. Чтобы собрать весь каталог в архив, можно использовать рекурсивный подход:
import os
import zipfile
def add_to_zip(zipf, path):
for root, dirs, files in os.walk(path):
for file in files:
file_path = os.path.join(root, file)
zipf.write(file_path, os.path.relpath(file_path, path))
with zipfile.ZipFile("directory.zip", "w", compression=zipfile.ZIP_DEFLATED) as zipf:
add_to_zip(zipf, "need_directory")
Работа с паролями
Собрали в кучку данные важные, а как же защита? Правильно, zipfile поддерживает защищенные паролем архивы.
# Запаковка
with zipfile.ZipFile('giga_secure.zip', 'w', compression=zipfile.ZIP_DEFLATED) as zipf:
zipf.setpassword(b'mypassword') # Пароль должен быть в байтах
zipf.write('file.txt')
# Распаковка
with zipfile.ZipFile('giga_secure.zip', 'r') as zipf:
zipf.extractall(pwd=b'mypassword')
Большие файлы
Если Сатурн вошел в Юпитер и тебе выпала судьба собрать в архив большие файлы, то вот тебе подсказка - используй потоковое чтение / запись:
with zipfile.ZipFile('large.zip', 'w', compression=zipfile.ZIP_DEFLATED) as zipf:
with open('large_file.txt', 'rb') as f:
zipf.writestr('large_file.txt', f.read())
Заключение
Итак, мы посмотрели с тобой на архивы. Немного покопались в них, чтобы научиться паковать, распаковывать, читать и т.д. Отложили на подкорке информацию о работе с паролями и большими файлаии. Осталось только напомнить об использовании try-except для обработки исключений и переменных окружения, чтобы твои пароли не утекали, как вода по трубе.