Подтвердить что ты не робот

Случайный доступ gzip stream

Я хотел бы иметь возможность делать произвольный доступ в gzip файл. Я могу позволить себе сделать некоторую предварительную обработку (например, построить какой-то индекс), при условии, что результат предварительной обработки намного меньше, чем сам файл.

Любые советы?

Мои мысли были:

  • Взломать существующую реализацию gzip и сериализовать ее состояние декомпрессора, скажем, 1 мегабайт сжатых данных. Затем, чтобы сделать произвольный доступ, десериализуйте состояние декомпрессора и прочитайте с границы мегабайта. Это кажется сложным, тем более, что я работаю с Java, и я не смог найти реализацию gzip pure-java: (
  • Скомпилируйте файл в кусках 1Mb и выполните то же самое, что и выше. Это имеет недостаток в удвоении необходимого дискового пространства.
  • Напишите простой синтаксический анализатор формата gzip, который не выполняет распаковки, и только обнаруживает и индексирует границы блоков (если даже есть какие-либо блоки: я еще не читал описание формата gzip)
4b9b3361

Ответ 1

Посмотрите по этой ссылке (пример кода на C).

/* zran.c -- example of zlib/gzip stream indexing and random access
...

Gzip - это просто zlib с огибающей.

Ответ 2

Формат файла BGZF, совместимый с GZIP, был разработан биологами.

(...) Преимущество BGZF над обычным gzip - это то, что BGZF позволяет искать, не имея для сканирования всего файла до поиск позиции.

В http://picard.svn.sourceforge.net/viewvc/picard/trunk/src/java/net/sf/samtools/util/, посмотрите на BlockCompressedOutputStream и BlockCompressedInputStream.java

Ответ 3

интересный вопрос. Я не понимаю, почему ваш второй вариант (recompress file in chunks) удваивает дисковое пространство. Кажется, что это будет одно и то же, меньше небольшого количества накладных расходов. Если у вас есть контроль над частью сжатия, тогда это кажется правильной идеей.

Возможно, вы имеете в виду, что у вас нет контроля над входом, и поэтому он будет удвоен.

Если вы можете это сделать, я представляю себе его моделирование как класс CompressedFileStream, который использует в качестве своего резервного хранилища серию 1mb gzip'd blobs. При чтении Seek() в потоке переместится к соответствующему блобу и распакуется. Прочитайте() после конца blob, чтобы поток открыл следующий blob.

ps: GZIP описан в IETF RFC 1952, но он использует DEFLATE для формата сжатия. Не было бы причин использовать разработку GZIP, если бы вы реализовали этот класс CompressedFileStream, как я себе представлял.

Ответ 4

FWIW: я разработал инструмент командной строки на основе исходного кода zlib zran.c, который создает индексы для файлов gzip: https://github.com/circulosmeos/gztool

Он может даже создать индекс для все еще растущего файла gzip (например, журнала, созданного rsyslog непосредственно в формате gzip), тем самым уменьшая на практике время создания индекса. Смотрите -S (Supervise).