Модуль Python Zipfile, кажется, не сжимает мои файлы

Я сделал небольшую вспомогательную функцию:

import zipfile

def main(archive_list=[],zfilename='default.zip'):
    print zfilename
    zout = zipfile.ZipFile(zfilename, "w")
    for fname in archive_list:
        print "writing: ", fname
        zout.write(fname)
    zout.close()

if __name__ == '__main__':
    main()  

Проблема в том, что все мои файлы не сжимаются! Файлы имеют одинаковый размер, и фактически просто расширение меняется на ".zip" (в данном случае с ".xls").

Я использую Python 2.5 на WinXP SP2.

3 ответа

Решение

Это потому что ZipFile требует от вас указать метод сжатия. Если вы не укажете это, предполагается, что метод сжатия будет zipfile.ZIP_STORED, который только хранит файлы без их сжатия. Вы должны указать метод, который будет zipfile.ZIP_DEFLATED, Вам нужно будет иметь zlib для этого установлен модуль (обычно он устанавливается по умолчанию).

import zipfile

def main(archive_list=[],zfilename='default.zip'):
    print zfilename
    zout = zipfile.ZipFile(zfilename, "w", zipfile.ZIP_DEFLATED) # <--- this is the change you need to make
    for fname in archive_list:
        print "writing: ", fname
        zout.write(fname)
    zout.close()

if __name__ == '__main__':
    main()  

Существует очень простой способ сжать 'zip file' формат,

Использовать в shutil.make_archive библиотека.

Например:

import shutil

shutil.make_archive(file_name, 'zip', file location after compression)

Более подробную документацию можно найти по адресу: https://docs.python.org/2/library/shutil.html.

Надеюсь, это будет кому-то полезно. Я протестировал все режимы zip и сравнил их на двух наборах данных. Первый маленький (~30 МБ), а другой большой (~ 1,5 ГБ). Они состояли из файлов разных типов, поэтому они были максимально приближены к реальному сценарию. Я провел два метода тестирования для каждого набора данных: «пропорциональный» и «полный». Оба теста повторялись 3 раза один за другим, чтобы получить среднее значение. Эти результаты могут отличаться в зависимости от ваших машин, но я думаю, что это хорошее место для начала.

Я провел тест двумя способами, потому что пытаюсь создать свое собственное специализированное решение для резервного копирования. Пропорциональный метод создает больше zip-файлов, но позволяет при необходимости передавать меньшие пакеты данных, например. замена только того, что поменяли. Это сложнее, но сейчас это не важно.

Полный метод - это просто сжатие всей папки.

Расчет степени сжатия:

size_difference = исходный_размер - сжатый_размер

соотношение_сжатия = (разница_размер * 100,0) / размер_источника

В основном, чем выше это число, тем лучше.

Каждый zip-архив был инициализирован следующим образом:

      # Mode tests
with zipfile.ZipFile(target_zip, 'w', compression_method) as ziph:

# Level tests
with zipfile.ZipFile(target_zip, 'w', compression_method, compresslevel=level) as ziph:

Вот результаты:

Кажется, что независимо от метода, наиболее оптимальный режим сжатия - ZIP_DEFLATED. Единственный меньший размер архива дал мне режим ZIP_LZMA, но он составлял лишь долю процента, а для больших наборов данных потребовалось примерно в 8 раз больше времени.

Кроме того, я пробовал разные уровни сжатия с одним и тем же набором данных и методами. За исключением того, что на этот раз было только одно прохождение на уровне.

Похоже, что ZIP_DEFLATED и ZIP_BIP2 имеют схожие возможности сжатия, но второй работает намного медленнее. Для больших наборов данных должно хватить уровня сжатия 1 или 2. Увеличение этого параметра не оказывает значительного влияния на конечный размер файла. Если рабочая нагрузка требует большого количества «маленьких» zip-файлов, лучше использовать уровень 9. Он дает высокую степень сжатия, но занимает примерно такое же количество времени, как и на уровне 1.

Другие вопросы по тегам