У меня смущающий параллельный процесс, который создает огромное количество почти (но не полностью) идентичных файлов. Есть ли способ архивировать файлы «на лету», чтобы данные не занимали больше места, чем необходимо?
Сам процесс принимает параметры командной строки и печатает имя каждого файла, созданного в стандартный вывод. Я вызываю его, parallel --gnu
который заботится о распределении входных данных (которые поступают из другого процесса) и сбора выходных данных:
arg_generating_process | parallel --gnu my_process | magic_otf_compressor
ПРОСТОЙ ПРИМЕР для первой части трубы в bash
:
for ((f = 0; $f < 100000; f++)); do touch $f; echo $f; done
Как может magic_otf_compressor
выглядеть? Предполагается, что каждая строка ввода рассматривается как имя файла, копирует каждый файл в сжатый .tar
архив (один и тот же архив для всех обработанных файлов!), А затем удаляет его. (На самом деле, этого должно быть достаточно, чтобы напечатать имя каждого обработанного файла, другой | parallel --gnu rm
может позаботиться об удалении файлов.)
Есть ли такой инструмент? Я не рассматриваю сжатие каждого файла по отдельности, это будет тратить слишком много места. Я изучил archivemount
(сохраню файловую систему в памяти -> невозможно, мои файлы слишком большие и слишком много) и avfs
(не смог заставить его работать вместе с FUSE). Что я пропустил?
Я всего в одном шаге от взлома такого инструмента сам, но кто-то должен был сделать это раньше ...
РЕДАКТИРОВАТЬ : По сути, я думаю, что я ищу внешний интерфейс stdin libtar
(в отличие от внешнего интерфейса командной строки, tar
который читает аргументы, ну, в общем, из командной строки).
источник
Ответы:
Кажется,
tar
хочет знать все имена файлов заранее. Так что это меньше на лету и больше на лету.cpio
не похоже, что эта проблема:источник
tar
код, чтобы увидеть, что есть функция, которая возвращает следующее имя файла для обработки, что заставило меня снова прочитать документацию. - Итак,stdout
направляется лиgzip
процесс через подстановку процесса иstderr
перенаправляется наstdout
который обрабатывается следующим шагом в конвейере?tar
сначала читает список файлов, используя простой пример, который я добавил к своему вопросу. Однако, снова читаяtar
исходный код , мне кажется, что он должен читать список файлов «на лету», если не создает инкрементный архив. К сожалению, у меня есть ошибки компиляцииtar
из исходного кода ... :-(cpio
, кромеgrep -v 'blocks$'
. (head -n -1
использует очень большой буфер ...) Делает это решение немногоhead -n -1
использует только 16 МБ при работе с несколькими ГБ данных. Вы всегда можете использовать perl: perl -ne 'print $ last; $ last = $ _'Классический случай RTFM (все это!) .
-T
Вариант GNUtar
будет читать файлы в архив из другого файла (в моем случае/dev/stdin
, вы можете также использовать-
), и есть даже--remove-files
вариант:(используется параллельная версия
xz
для сжатия, но вместо этого вы можете использовать предпочитаемый компрессор). Для использования в качестве:РЕДАКТИРОВАТЬ : Как указывает Оле,
tar
кажется, по-T
какой-то причине читает весь список файлов с опцией. Следующий тест подтверждает это:В моей системе задержка составляет одну секунду, прежде чем все файлы печатаются одновременно; напротив, если
tar
команда заменяется наcat
, все файлы печатаются по мере их создания. Я подал запрос в службу поддержки пользователей tar, давайте посмотрим.РЕДАКТИРОВАТЬ ^ 2 :
tar
это исправлено в последних источниках. Это еще не в Ubuntu 13.10, но может быть включено с 14.04.источник
Почему-то это не очень хорошая работа для твердого компрессора (ленточные архиваторы + сжатие). Вставка файлов один за другим выглядит как задание
zip
или какой-то другой формат, который обеспечивает произвольный доступ к файлам в архиве и добавочную вставку.Тот факт, что файлы похожи, не очень поможет в любом случае. В этом случае
zip
файлы сжимаются отдельно, а в сплошных компрессорах обычно имеется окно, в котором происходит сжатие.Если файлы основаны на тексте, вы можете хранить различия по сравнению с одним справочным файлом. Для двоичного кода это немного сложнее, но может быть сделано.
Существует также формальный способ (не только для записи, но и правильные файловые системы). Например, файловые системы ZFS и BTRFS обеспечивают прозрачное сжатие. Вы также можете использовать этот http://developer.berlios.de/projects/fusecompress
источник
xz
Кажется, что он работает с размером словаря по умолчанию 8M (при уровне сжатия по умолчанию-6
), что вполне достаточно для моего варианта использования. - Отличия от эталонного файла - это хорошо, но сначала нужно создать эталонный файл. Будет ли сжатая файловая система обнаруживать файлы с почти одинаковым содержимым?btrfs
имеет функцию копирования при записи, поэтому, если вы копируете файл и изменяете его часть, он сохраняет только те части, которые вы изменили. Если вы не создаете файлы таким образом, предположительно существуют инструменты дедупликации , ноbtrfs
это еще не зрелая и стабильная файловая система, и дедупликация находится на ранних стадиях разработки. Но теперь я думаю об этом, как насчет lessfs.com/wordpressЭто может показаться неочевидным, но я держу пари,
squashfs
что это идеально подходит для этого - и даже реализовано в ядре. Поскольку версия 4.1squashfs
может обрабатывать псевдофайлы, как указано вmksquash
командной строке или с помощью сценария оболочки, иmksquashfs
будет генерировать файлы при создании архива.Он может обрабатывать каналы - например, вы можете записать другой процесс
stdout
в монтируемый архив сквоша - даже пятнадцать - это довольно круто. В вашем случае, если вы могли бы отработать скрипт логистику трубопровода выхода вашего процесса через него, вы можете обернуть процесс полностью вmksquashfs
и ветре с одним архивом. Вот немногоreadme
о том, как это работает, и это еще не все :источник
test
и файломfile
в этом каталоге. Не могли бы вы привести краткий пример?