2010-07-25 2 views
14

Скажем, file.txt.gz имеет 2 ГБ, и я хочу увидеть последние 100 строк или около того. zcat <file.txt.gz | tail -n 100 будет проходить через все это.Чтение последних строк текстового файла gzipped

Я понимаю, что сжатые файлы не могут быть случайным образом доступны, и если я разрежу, скажем, последние 5 МБ, то данные сразу после разреза будут мусором - но может ли gzip повторно синхронизировать и декодировать остальную часть потока?

Если я правильно понимаю, поток gzip - это простой поток команд, описывающих, что выводить - с ним должна быть возможность синхронизироваться. Тогда есть 32kB скользящее окно из последних несжатых данных, которое начинается как мусор, конечно, если мы начнем посередине, но я бы предположил, что он, как правило, быстро заполняется реальными данными, и с этой точки декомпрессия тривиальна (ну, возможно, что что-то повторяется снова и снова от начала файла до конца, и поэтому скользящее окно никогда не очищается - меня это удивило бы, если бы все было так часто, и если это произойдет, мы просто обработаем весь файл).

Я не страшно желаю сделать этот род gzip hackery самостоятельно - никто раньше не делал этого, чтобы иметь дело с поврежденными файлами, если ничего другого?

В качестве альтернативы - если gzip действительно не может этого сделать, существуют ли, возможно, какие-либо другие программы сжатия потока, которые очень похожи на него, за исключением того, что они позволяют выполнять повторную синхронизацию в середине потока?

EDIT: Я нашел pure Ruby reimplementation of zlib и взломал его, чтобы напечатать возраст байтов в скользящем окне. Оказывается, что вещи много раз копируются и даже после 5 Мбайт + скользящее окно все еще содержит материал из первых 100 байт и из случайных мест по всему файлу.

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

По существу, варианты по умолчанию, что я хотел, возможно, невозможно.

С другой стороны, zlib имеет Z_FULL_FLUSH вариант, который очищает это скользящее окно для синхронизации. Так что вопрос все еще стоит. Предполагая, что zlib синхронизирует время от времени, есть ли какие-либо инструменты для чтения только конца этого, не обрабатывая все это?

+0

Проверьте дублированный вопрос http://stackoverflow.com/questions/14225751/random-access-to-gzipped-files и zran http://www.zlib.net/zlib_faq.html#faq28 –

+1

Этот вопрос действительно имеет не имеет ничего общего с моей проблемой, «Z_FULL_FLUSH» было настоящим решением. – taw

+0

Прохладный! Можете ли вы опубликовать свое решение? –

ответ

1

Z_FULL_FLUSH испускает известную последовательность байтов (00 00 FF FF), которую вы можете использовать для синхронизации. This link может быть полезным.

+6

ссылка мертва ... – stepancheg

0

В этом разница между блочными и потоковыми шифрами. Поскольку gzip - это потоковый шифр, вам может понадобиться весь файл до определенной точки для дешифрования байтов в этой точке.

Как вы упомянули, когда окно очищено, вы золотые. Но нет никакой гарантии, что zlib действительно делает это достаточно часто для вас ... Я предлагаю вам искать назад с конца файла и найти маркер для полного флеша.