1

Я ищу способ объединить несколько файлов tar.gz быстро.

Вариант использования: клиент нажимает кнопку загрузки и получает файл tar.gz. Существует опция конфигурации для добавления дополнительной информации к исходящей загрузке в графическом интерфейсе нашего приложения. Если выбрана эта опция, мне нужно объединить дополнительные файлы tar.gz для исходящей загрузки.

Я работаю с большим количеством данных здесь. При распаковке дополнительные файлы tar.gz превышают ГБ. Кроме того, файл tar.gz по умолчанию, который всегда доставляется, может быть более 10 ГБ в несжатом виде и может содержать более 100 файлов. Из-за больших размеров данных, с которыми я работаю, они хранятся в сжатом формате (tar.gz) на диске.

Я ищу, чтобы реализовать этот механизм в Bash Script или в Java.

1 ответ1

2

TLDR: обычно их можно просто объединить

Формат файла usd от gzip разработан таким образом, что объединение двух или более сжатых файлов и распаковка результата дает вам те же данные, что и при объединении несжатых версий; см. https://stackoverflow.com/questions/8005114/fast-concatenation-of-multiple-gzip-files
https://stackoverflow.com/questions/16715484/can-multiple-gz-files-be-combined-such-that-they-extract-into-a-single-file

Примерно так же формат tar изначально разрабатывался так, чтобы вы могли просто добавлять записи в конец архива. Это было эффективно необходимо, потому что «(t)ape (ar)chive» был разработан и использовал магнитную ленту для резервного копирования и обмена, а накопители на магнитных лентах 1950–1980-х годов (примерно) не могли безопасно «переписать» (обновление) существующие данные только дополняют до конца. (Эти накопители могли разделять логические файлы на ленте с помощью «метки ленты», но системы Unix не поддерживали метаданные, также известные как метки на магнитной ленте, и управление большим количеством файлов на магнитной ленте только по физической числовой позиции было PITA, поэтому использование tar для добавления существующему архиву было гораздо предпочтительнее.)

В последние годы это стало гораздо менее распространенным явлением, и теперь GNU tar не поддерживает его по умолчанию; Вы должны указать -i (или длинную форму --ignore-zeros), и тогда он будет работать нормально:

$ printf 'ONEONEONE%90d\n' {0..99999} >file1
$ printf 'TWOTWOTWO%90d\n' {0..199999} >file2
$ ll
total 29300
-rw-r--r--. 1 dthomps users 10000000 Sep  9 02:14 file1
-rw-r--r--. 1 dthomps users 20000000 Sep  9 02:15 file2
$ tar -czf tar1.tgz file1
$ tar -czf tar2.tgz file2
    # or tar -cf - file1 |gzip >tar1.tgz and similarly for 2, see below
$ cat tar2.tgz tar1.tgz >combined.tgz
$ tar -tvzif combined.tgz
-rw-r--r-- dthomps/users 20000000 2016-09-09 02:15 file2
-rw-r--r-- dthomps/users 10000000 2016-09-09 02:14 file1
  # or gunzip <combined.tgz |tar -tvif - see below
$

Старые tars могут поддерживать объединение архивов по умолчанию (нет -i); если у меня будет время раскрутить некоторые из моих старых тестовых систем позже, я обновлю. Однако они обычно не поддерживают интегрированное сжатие -z как gtar, поэтому вам нужно использовать tar cf - | gzip > и gunzip < | tar -xf - формы.

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .