Сжатие и разбиение файлов с Python
Данные операции решают проблемы перемещения файлов большого размера на удаленный сервер и обратно. Быстро разберемся с ними и автоматизируем процесс, чтобы избежать лишних расходов драгоценного времени.
Для последующих манипуляций будем использовать модуль zipfile.
Создание архива
Для этого потребуется создать экземпляр класса ZipFile и вызвать его метод write с указанием пути к файлу, который помещается в архив. Напишем простой блок кода, который архивирует заданную папку:
import zipfile import os dir_source = 'source' arch_fn = 'data' with zipfile.ZipFile(f'{arch_fn}.zip', 'w') as zip_f: for folder, subfolders, filenames in os.walk(dir_source): for filename in filenames: zip_f.write(os.path.join(folder, filename))
Получение информации об архиве
Опять же сначала потребуется создать экземпляр класса ZipFile. Список названий входящих в архив файлов можно получить, обратившись к методу namelist, а размеры файлов и их сжатых копий из свойств объекта информации о содержимом (file_size, compress_size), получаемого через метод getinfo. Продемонстрируем вывод информации о содержимом архива на примере:
zip_f = zipfile.ZipFile(f'{arch_fn}.zip') for fn in zip_f.namelist(): info = zip_f.getinfo(fn) print(f'файл - {fn}, размер - {info.file_size}, сжатый размер - {info.compress_size}')
Извлечение файлов из архива
Для этого создается экземпляр класса ZipFile и вызывается его метод extract или extractall для извлечения конкретного или всех файлов. При этом в обоих можно указать путь к папке, иначе копирование происходит в рабочий каталог. Вот как полностью извлечь архив в заданную папку:
dir_out = 'output' zip_f = zipfile.ZipFile(f'{arch_fn}.zip') zip_f.extractall(dir_out)
Дальнейшие операции происходят с использованием модуля filesplit. Для работы потребуется создать экземпляр класса Filesplit:
from fsplit.filesplit import Filesplit fs = Filesplit()
Разбиение
Затем разбиение производится методом split с указанием файла, размера части в байтах, выходной директории (если не указана, то текущая) и, возможно, callback функции, вызываемой после формирования каждой части:
dir_pieces = 'pieces' if not os.path.exists(dir_pieces): os.mkdir(dir_pieces) def split_cb(f, s): print("file: {0}, size: {1}".format(f, s)) fs.split(file=f'{arch_fn}.zip', split_size=50000, output_dir=dir_pieces, callback=split_cb)
Объединение
Данная операция выполняется методом merge объекта класса Filesplit:
def merge_cb(f, s): print("file: {0}, size: {1}".format(f, s)) fs.merge(input_dir=f'{arch_fn}.zip', callback=merge_cb)
Обязательный параметр только путь к папке с набором частей, также по выбору можно задать выходной файл (либо будет создан в той же папке, где и части) и callback функцию: