Модуль 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.