Предположим, у меня есть 10000 XML-файлов. Теперь предположим, что я хочу отправить их другу. Перед отправкой я бы хотел их сжать.
Способ 1: не сжимайте их
Результаты:
Resulting Size: 62 MB
Percent of initial size: 100%
Способ 2: Zip каждый файл и отправьте ему 10000 XML-файлов
Команда:
for x in $(ls -1) ; do echo $x ; zip "$x.zip" $x ; done
Результаты:
Resulting Size: 13 MB
Percent of initial size: 20%
Способ 3: создать один ZIP-файл, содержащий 10000 XML-файлов
Команда:
zip all.zip $(ls -1)
Результаты:
Resulting Size: 12 MB
Percent of initial size: 19%
Способ 4: объединить файлы в один файл и заархивировать его
Команда:
cat *.xml > oneFile.txt ; zip oneFile.zip oneFile.txt
Результаты:
Resulting Size: 2 MB
Percent of initial size: 3%
Вопросов:
- Почему я получаю такие значительно лучшие результаты, когда просто архивирую один файл?
- Я ожидал получить значительно лучшие результаты, используя метод 3, чем метод 2, но не получаю. Почему?
- Это поведение специфично для
zip
? Если бы я попытался использоватьgzip
, я получил бы другие результаты?
Дополнительная информация:
$ zip --version
Copyright (c) 1990-2008 Info-ZIP - Type 'zip "-L"' for software license.
This is Zip 3.0 (July 5th 2008), by Info-ZIP.
Currently maintained by E. Gordon. Please send bug reports to
the authors using the web page at www.info-zip.org; see README for details.
Latest sources and executables are at ftp://ftp.info-zip.org/pub/infozip,
as of above date; see http://www.info-zip.org/ for other sites.
Compiled with gcc 4.4.4 20100525 (Red Hat 4.4.4-5) for Unix (Linux ELF) on Nov 11 2010.
Zip special compilation options:
USE_EF_UT_TIME (store Universal Time)
SYMLINK_SUPPORT (symbolic links supported)
LARGE_FILE_SUPPORT (can read and write large files on file system)
ZIP64_SUPPORT (use Zip64 to store large files in archives)
UNICODE_SUPPORT (store and read UTF-8 Unicode paths)
STORE_UNIX_UIDs_GIDs (store UID/GID sizes/values using new extra field)
UIDGID_NOT_16BIT (old Unix 16-bit UID/GID extra field not used)
[encryption, version 2.91 of 05 Jan 2007] (modified for Zip 3)
Изменить: метаданные
Один ответ предполагает, что различие заключается в системных метаданных, которые хранятся в zip-архиве. Я не думаю, что это может быть так. Чтобы проверить, я сделал следующее:
for x in $(seq 10000) ; do touch $x ; done
zip allZip $(ls -1)
Полученный почтовый индекс составляет 1,4 МБ. Это означает, что все еще остается ~ 10 МБ необъяснимого пространства.
.tar.gz
а не просто архивировать весь каталог.$(ls -1)
просто использовать*
:for x in *
;zip all.zip *
Ответы:
Zip обрабатывает содержимое каждого файла отдельно при сжатии. Каждый файл будет иметь свой собственный сжатый поток. В алгоритме сжатия есть поддержка (как правило, DEFLATE ) для идентификации повторяющихся разделов. Однако в Zip отсутствует поддержка поиска избыточности между файлами.
Вот почему так много дополнительного пространства, когда контент находится в нескольких файлах: он помещает один и тот же сжатый поток в файл несколько раз.
источник
there is no support in Zip to find redundancy between files
это в спецификации файла zip?Сжатие ZIP основано на повторяющихся шаблонах в сжимаемых данных, и сжатие тем лучше, чем дольше файл, так как можно найти и использовать все больше и больше шаблонов.
Упрощенно, если вы сжимаете один файл, словарь, который отображает (короткие) коды в (более длинные) шаблоны, обязательно содержится в каждом результирующем zip-файле; если вы заархивируете один длинный файл, словарь будет «повторно использован» и станет еще более эффективным для всего контента.
Если ваши файлы даже немного похожи (как текст всегда), повторное использование «словаря» становится очень эффективным, и в результате получается намного меньший общий zip.
источник
В Zip каждый файл сжимается отдельно. Противоположностью является «сплошное сжатие», то есть файлы сжимаются вместе. 7-zip и Rar по умолчанию используют сплошное сжатие. Gzip и Bzip2 не могут сжимать несколько файлов, поэтому сначала используется Tar, что дает тот же эффект, что и сплошное сжатие.
Поскольку XML-файл имеет схожую структуру и, возможно, схожий контент, если файлы сжаты вместе, сжатие будет выше.
Например, если файл содержит строку
"<content><element name="
и компрессор уже обнаружил эту строку в другом файле, он заменит ее небольшим указателем на предыдущее совпадение, если компрессор не использует «сплошное сжатие» при первом вхождении строки в файл будет записан как литерал, который больше.источник
Zip хранит не только содержимое файла, но и метаданные файла, такие как идентификатор пользователя, права доступа, время создания и изменения и так далее. Если у вас есть один файл, у вас есть один набор метаданных; если у вас есть 10 000 файлов, у вас есть 10 000 наборов метаданных.
источник
Опция, пропущенная OP, заключается в том, чтобы сжать все файлы вместе с выключенным сжатием, а затем сжать получившийся архив с максимальным сжатием. Это примерно имитирует поведение сжатых архивов * nix .tar.Z, .tar.gz, .tar.bz и т. Д., Позволяя сжатию использовать избыточность через границы файлов (чего не может сделать алгоритм ZIP при запуске в одном проходят). Это позволяет извлекать отдельные XML-файлы позже, но максимизирует сжатие. Недостатком является то, что процесс извлечения требует дополнительного шага, временно используя гораздо больше дискового пространства, чем было бы необходимо для обычного .zip.
С распространением бесплатных инструментов, таких как 7-Zip, для расширения семейства tar до Windows, нет никаких оснований не использовать .tar.gz или .tar.bz и т. Д., Как у Linux, OS X и BSD. родные инструменты для манипулирования ими.
источник
xz
/ 7-zip). В любом случае, адаптивные словари могут распознавать шаблоны, как только они видны. Это не похоже на то, чтобы просто построить статическую систему кодирования на основе первых 32 КБ. Вот почему gzip не сосет.Формат сжатия zip хранит и сжимает каждый файл отдельно. Он не использует повторение между файлами, только внутри файла.
Конкатенация файлов позволяет zip использовать преимущества повторений для всех файлов, что приводит к значительному увеличению сжатия.
Например, скажем, каждый файл XML имеет определенный заголовок. Этот заголовок встречается только один раз в каждом файле, но почти одинаково повторяется во многих других файлах. В методах 2 и 3 zip не может сжать для этого, но в методе 4 это может.
источник
Рядом с метаданными, упомянутыми Майком Скоттом, есть также издержки в алгоритме сжатия.
При сжатии нескольких отдельных небольших файлов вам будет очень повезло, что вы сможете сжать их так, что это просто заполняет один блок сжатия. При сжатии одного монолитного блока система может просто продолжать передавать данные в свой алгоритм, игнорируя «границы» (из-за отсутствия лучшего слова) отдельных файлов.
Также известно, что ASCII имеет высокий коэффициент сжатия. Кроме того, XML часто очень повторяется, что делает метаданные большой частью данных, которые не могут быть так легко сжаты, как содержимое XML.
И наконец, если память работает правильно, zip использует что-то вроде словарной кодировки, что особенно эффективно для файлов ASCII и, тем более, для XML из-за их повторяемости
Объяснение сжатия данных: http://mattmahoney.net/dc/dce.html
источник
Рассмотрим этот XML:
XML имеет очень повторяющуюся структуру, Zip использует эти повторы для создания словаря, в котором шаблон встречается чаще, а затем при сжатии использует меньше битов для хранения более повторяющихся шаблонов и больше битов для хранения менее повторяющихся шаблонов .
Когда вы объединяете эти файлы, исходный файл (источник для zip) большой, но содержит гораздо более повторяющиеся шаблоны, потому что распределение большого количества скучных структур XML амортизируется в большом целом файле, давая возможность ZIP сохранять эти шаблоны. используя меньше битов.
Теперь, если вы объедините разные XML в один файл, даже если эти файлы имеют совершенно разные имена тегов, алгоритм сжатия найдет наилучшее распределение шаблонов по всем файлам, а не файл за файлом.
В конечном итоге алгоритм сжатия нашел наилучшее повторное распределение паттернов.
источник
В дополнение к ответу 7-Zip есть еще один подход, который не так хорош, но стоит попробовать, если по какой-то причине вы не хотите использовать 7-Zip:
Сожмите почтовый файл. Теперь обычно zip-файл является несжимаемым, но когда он содержит много идентичных файлов, компрессор может найти эту избыточность и сжать ее. Обратите внимание, что я также видел небольшой выигрыш при работе с большим количеством файлов без избыточности. Если вы действительно заботитесь о размере, стоит попробовать, если у вас в архиве очень много файлов.
источник