Как я могу записать заархивированный файл, не читая все его содержимое? - PullRequest
40 голосов
/ 26 июля 2009

Я хочу эмулировать функциональность gzcat |tail -n.

Это было бы полезно для случаев, когда есть большие файлы (размером в несколько ГБ или около того). Могу ли я записать последние несколько строк такого файла без чтения с самого начала? Я сомневаюсь, что это будет невозможно, так как я предполагаю, что для gzip кодировка будет зависеть от всего предыдущего текста.

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

Ответы [ 7 ]

40 голосов
/ 26 июля 2009

Нет, вы не можете. Алгоритм zipping работает с потоками и адаптирует свои внутренние кодировки к тому, что содержится в потоке, для достижения высокой степени сжатия.

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

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

8 голосов
/ 12 февраля 2013

BGZF используется для создания индексированных сжатых GZIP BAM-файлов, созданных Samtools. Они доступны в произвольном порядке.

http://samtools.sourceforge.net/

3 голосов
/ 26 июля 2009

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

1 голос
/ 04 мая 2015

zindex создает и запрашивает индекс сжатого текстового файла на основе строк с эффективным использованием времени и пространства.

https://github.com/mattgodbolt/zindex

1 голос
/ 24 ноября 2014

Если это опция, тогда bzip2 может быть лучшим алгоритмом сжатия для этой цели.

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

Размер блока выбирается ввремя файл написан. Фактически, это то, что происходит, когда вы устанавливаете -1 (или --fast) в -9 (или --best) в качестве опций сжатия, которые соответствуют размерам блоков от 100k до 900k. Значение по умолчанию - 900k.

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

0 голосов
/ 25 июля 2019

Ну, вы можете сделать это, если вы ранее создали index для каждого файла ...

Я разработал инструмент командной строки, который создает индексы для файлов gzip, которые обеспечивают очень быстрый произвольный доступ внутри них , и это чередуется с действиями (извлечение, хвост, непрерывный хвост и т. д.): https://github.com/circulosmeos/gztool

Но вы можете сделатьхвост (-t), и индекс будет создан автоматически: если вы собираетесь сделать то же самое в будущем, это будет намного быстрее, и в любом случае в первый раз это займет то же время, что и gunzip | tail:

$ gztool -t my_file.gz
0 голосов
/ 15 июля 2018

Пример полностью псевдослучайного формата, полностью совместимого с gzip: dictzip:

Для сжатия файл разбивается на «порции» данныхкаждый кусок меньше 64 кБ. [...]

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...