Мгновенная печать списка архивных файлов (без распаковки всего архива)


10

Проблема с .tar.gzархивами заключается в том, что, когда я пытаюсь просто перечислить содержимое архива, компьютер фактически распаковывает его, что может занять очень много времени, если файл большой.

Другие форматы файлов , такие как .7z, .rar, .zipне имеют этой проблемы. Перечисление их содержания занимает всего одно мгновение.

По моему наивному мнению, это огромный недостаток .tar.gzформата архива.

Итак, у меня фактически есть 2 вопроса:

  1. почему люди .tar.gzтак много используют, несмотря на этот недостаток?
  2. Какой выбор (я имею в виду другое программное обеспечение или инструменты) у меня есть, если я хочу возможность «мгновенного отображения контента»?

Возможный дубликат [ superuser.com/questions/565883/… .
agc

Gunzip это первым?
Джефф Шаллер

Ответы:


18

Важно понимать, что здесь есть компромисс.

tarозначает ленточный архиватор . На ленте вы делаете в основном последовательное чтение и запись. В настоящее время ленты используются редко, но tarвсе еще используются для его способности читать и записывать свои данные в виде потока.

Ты можешь сделать:

tar cf - files | gzip | ssh host 'cd dest && gunzip | tar xf -'

Вы не можете сделать это с zipили тому подобное.

Вы даже не можете перечислить содержимое zipархива, не сохранив его локально в доступном для поиска файле. Думает как:

curl -s https://github.com/dwp-forge/columns/archive/v.2016-02-27.zip | unzip -l /dev/stdin

не сработает

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

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

Еще один недостаток таких форматов, как zipто, что архивирование связано со сжатием, вы не можете выбрать алгоритм сжатия. Посмотрите, как tarархивы раньше сжимались с помощью compress( tar.Z), затем с gzip, затем bzip2, тогда, xzкогда были разработаны новые более производительные алгоритмы сжатия. То же самое касается шифрования. Кто будет доверять zipшифрованию в наше время?

Теперь проблема с tar.gzархивами заключается не в том, что вам нужно их распаковывать. Распаковка часто происходит быстрее, чем чтение с диска (вы, вероятно, обнаружите, что распечатка содержимого большого архива tgz быстрее, чем распечатка того же распакованного, когда он не кэширован в памяти), но вам нужно прочитать весь архив.

Неспособность быстро прочитать индекс - не проблема. Если вы предвидите необходимость часто читать содержимое таблицы архива, вы можете просто сохранить этот список в отдельном файле. Например, во время создания вы можете сделать:

tar cvvf - dir 2> file.tar.xz.list | xz > file.tar.xz

Более серьезной проблемой IMO является тот факт, что из-за последовательного аспекта архива вы не можете извлечь отдельные файлы, не прочитав весь начальный раздел архива, который ведет к нему. IOW, вы не можете делать случайные чтения в архиве.

Теперь, для поиска файлов, это не должно быть так.

Если вы сжимаете свой tarархив gzip, который сжимает его как единое целое, алгоритм сжатия использует данные, которые были видны в начале, чтобы сжимать, поэтому вы должны начать с начала, чтобы распаковать.

Но xzформат может быть сконфигурирован для сжатия данных в отдельных отдельных чанках (достаточно больших, чтобы сжатие было эффективным), это означает, что до тех пор, пока вы сохраняете индекс в конце этих сжатых чанков, для доступных для поиска файлов вы получаете доступ к несжатые данные случайным образом (по крайней мере, кусками).

pixz(параллельно xz) использует эту возможность при сжатии tarархивов, чтобы также добавить индекс начала каждого элемента архива в конце xzфайла.

Таким образом, для доступных для поиска файлов вы можете не только получить список содержимого архива tar мгновенно (но без метаданных), если они были сжаты с помощью pixz:

pixz -l file.tar.xz

Но вы также можете извлечь отдельные элементы, не читая весь архив:

pixz -x archive/member.txt < file.tar.xz | tar xpf -

Теперь, почему такие вещи, как 7zили zipредко используются в Unix, в основном потому, что они не могут архивировать файлы Unix. Они были разработаны для других операционных систем. Вы не можете сделать точную резервную копию данных, используя их. Они не могут хранить метаданные, такие как владелец (идентификатор и имя), разрешение, они не могут хранить символические ссылки, устройства, fifos ..., они не могут хранить информацию о жестких ссылках и другую информацию метаданных, такую ​​как расширенные атрибуты или ACL.

Некоторые из них не могут даже хранить элементы с произвольными именами (некоторые будут задыхаться от обратной косой черты, или новой строки, или двоеточия, или имен файлов, отличных от ascii) ( tarхотя некоторые форматы также имеют ограничения).

Никогда не распаковывайте файл tgz / tar.xz на диск!

В случае , если это не очевидно, один не использовать tgzили tar.bz2, tar.xz... архив как:

unxz file.tar.xz
tar tvf file.tar
xz file.tar

Если .tarв вашей файловой системе лежит несжатый файл, значит, вы сделали что-то не так.

Весь смысл этих xz / bzip2/ gzipпотоковых компрессоров заключается в том, что они могут использоваться на лету, в трубопроводах, как в

unxz < file.tar.xz | tar tvf -

Хотя современные tarреализации знают, как вызыватьunxz / gunzip/ bzip2самостоятельно, поэтому:

tar tvf file.tar.xz

обычно также работает (и снова распаковывает данные на лету, а не сохраняет несжатую версию архива на диске).

пример

Вот дерево исходного кода ядра Linux, сжатое в различных форматах.

$ ls --block-size=1 -sS1
666210304 linux-4.6.tar
173592576 linux-4.6.zip
 97038336 linux-4.6.7z
 89468928 linux-4.6.tar.xz

Во-первых, как отмечалось выше, 7z и zip немного отличаются, потому что они не могут хранить там несколько символических ссылок и пропускают большую часть метаданных.

Теперь несколько моментов для отображения содержимого после очистки системных кэшей:

$ echo 3 | sudo tee /proc/sys/vm/drop_caches
3
$ time tar tvf linux-4.6.tar > /dev/null
tar tvf linux-4.6.tar > /dev/null  0.56s user 0.47s system 13% cpu 7.428 total
$ time tar tvf linux-4.6.tar.xz > /dev/null
tar tvf linux-4.6.tar.xz > /dev/null  8.10s user 0.52s system 118% cpu 7.297 total
$ time unzip -v linux-4.6.zip > /dev/null
unzip -v linux-4.6.zip > /dev/null  0.16s user 0.08s system 86% cpu 0.282 total
$ time 7z l linux-4.6.7z > /dev/null
7z l linux-4.6.7z > /dev/null  0.51s user 0.15s system 89% cpu 0.739 total

Вы заметите, что листинг tar.xzфайла быстрее, чем.tar даже на этом 7-летнем ПК, поскольку чтение этих дополнительных мегабайт с диска занимает больше времени, чем чтение и распаковка меньшего файла.

Тогда хорошо, перечисление архивов с помощью 7z или zip происходит быстрее, но это не проблема, поскольку, как я уже сказал, это легко обойти, сохранив список файлов рядом с архивом:

$ tar tvf linux-4.6.tar.xz | xz > linux-4.6.tar.xz.list.xz
$ ls --block-size=1 -sS1 linux-4.6.tar.xz.list.xz
434176 linux-4.6.tar.xz.list.xz
$ time xzcat linux-4.6.tar.xz.list.xz > /dev/null
xzcat linux-4.6.tar.xz.list.xz > /dev/null  0.05s user 0.00s system 99% cpu 0.051 total

Даже быстрее чем 7z или zip даже после сброса кешей. Вы также заметите, что совокупный размер архива и его индекс по-прежнему меньше, чем у архивов zip или 7z.

Или используйте pixzиндексированный формат:

$ xzcat linux-4.6.tar.xz | pixz -9  > linux-4.6.tar.pixz
$ ls --block-size=1 -sS1 linux-4.6.tar.pixz
89841664 linux-4.6.tar.pixz
$ echo 3 | sudo tee /proc/sys/vm/drop_caches
3
$ time pixz -l linux-4.6.tar.pixz > /dev/null
pixz -l linux-4.6.tar.pixz > /dev/null  0.04s user 0.01s system 57% cpu 0.087 total

Теперь, чтобы извлечь отдельные элементы архива, наихудший сценарий для архива tar - это доступ к последнему элементу:

$ xzcat linux-4.6.tar.xz.list.xz|tail -1
-rw-rw-r-- root/root      5976 2016-05-15 23:43 linux-4.6/virt/lib/irqbypass.c
$ time tar xOf linux-4.6.tar.xz linux-4.6/virt/lib/irqbypass.c | wc
    257     638    5976
tar xOf linux-4.6.tar.xz linux-4.6/virt/lib/irqbypass.c  7.27s user 1.13s system 115% cpu 7.279 total
wc  0.00s user 0.00s system 0% cpu 7.279 total

Это довольно плохо, так как нужно читать (и распаковывать) весь архив. Сравнить с:

$ time unzip -p linux-4.6.zip linux-4.6/virt/lib/irqbypass.c | wc
    257     638    5976
unzip -p linux-4.6.zip linux-4.6/virt/lib/irqbypass.c  0.02s user 0.01s system 19% cpu 0.119 total
wc  0.00s user 0.00s system 1% cpu 0.119 total

Моя версия 7z не может выполнять произвольный доступ, поэтому она выглядит еще хуже, чем tar.xz:

$ time 7z e -so linux-4.6.7z linux-4.6/virt/lib/irqbypass.c 2> /dev/null | wc
    257     638    5976
7z e -so linux-4.6.7z linux-4.6/virt/lib/irqbypass.c 2> /dev/null  7.28s user 0.12s system 89% cpu 8.300 total
wc  0.00s user 0.00s system 0% cpu 8.299 total

Теперь, так как мы создали наш pixzранее:

$ time pixz < linux-4.6.tar.pixz -x linux-4.6/virt/lib/irqbypass.c  | tar xOf - | wc
    257     638    5976
pixz -x linux-4.6/virt/lib/irqbypass.c < linux-4.6.tar.pixz  1.37s user 0.06s system 84% cpu 1.687 total
tar xOf -  0.00s user 0.01s system 0% cpu 1.693 total
wc  0.00s user 0.00s system 0% cpu 1.688 total

Это быстрее, но все еще относительно медленно, потому что архив содержит несколько больших блоков:

$ pixz -tl linux-4.6.tar.pixz
 17648865 / 134217728
 15407945 / 134217728
 18275381 / 134217728
 19674475 / 134217728
 18493914 / 129333248
   336945 /   2958887

Поэтому по- pixzпрежнему необходимо читать и распаковывать (до) ~ 19 МБ большой кусок данных.

Мы можем сделать произвольный доступ быстрее, сделав архивы меньшими блоками (и пожертвовав немного дискового пространства):

$ pixz -f0.25 -9 < linux-4.6.tar > linux-4.6.tar.pixz2
$ ls --block-size=1 -sS1 linux-4.6.tar.pixz2
93745152 linux-4.6.tar.pixz2
$ time pixz < linux-4.6.tar.pixz2 -x linux-4.6/virt/lib/irqbypass.c  | tar xOf - | wc
    257     638    5976
pixz -x linux-4.6/virt/lib/irqbypass.c < linux-4.6.tar.pixz2  0.17s user 0.02s system 98% cpu 0.189 total
tar xOf -  0.00s user 0.00s system 1% cpu 0.188 total
wc  0.00s user 0.00s system 0% cpu 0.187 total

«Неспособность быстро прочитать индекс - не проблема». Напротив, это ограничитель показа, когда не хватает места или времени даже для распаковки файла. Предложить: 's / Not / Иногда нет /'
agc

1
@agc, смотрите правку с парой дополнительных разделов. Надеюсь, это проясняет это. Вам, конечно, не нужно дополнительное место на диске для просмотра содержимого архива.
Стефан Шазелас

1
Пожалуйста, простите меня, SC, ваши дополнения хорошо приняты (особенно в отношении дискового пространства и списка архивов), но я в основном имел в виду конъюнктивный или включающий "или" здесь: "недостаточно места или времени" - то есть набор, включающий оба , один или другой. Иногда ситуации застают пользователей неподготовленными, и без описанной вами предварительной подготовки большая работа .tar.gzможет занять слишком много времени. Особенно если среда медленная. Тогда формат архива становится различием между невозможным и практическим.
agc

@ StéphaneChazelas: ваш ответ хороший и исчерпывающий, но я думаю, что вы должны отредактировать часть о pixz - может показаться, что проект редко обслуживается и имеет много проблем, поэтому его лучше не использовать для резервного копирования важных данных, в моем мнение.
Максим

3
  1. почему люди так часто его используют, несмотря на этот недостаток?

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

  1. Какой выбор (я имею в виду другое программное обеспечение / инструмент) у меня есть, если я хочу возможность «мгновенного отображения контента»?

dar ( D isk Ar chiver) включает в себя множествофункций, похожихна tar , а также такие усовершенствования, как быстрый произвольный доступ к сжатым архивам, каталогизация AKA, индексация AKA, AKA «мгновенный листинг контента» ...

Смотрите также: форматы сжатия с хорошей поддержкой произвольного доступа в архивах?

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.