Ответ 1
Z_FULL_FLUSH выдает известную последовательность байтов (00 00 FF FF), которую вы можете использовать для синхронизации. Эта ссылка может быть полезна.
Скажем, file.txt.gz
имеет 2 ГБ, и я хочу увидеть последние 100 строк или около того. zcat <file.txt.gz | tail -n 100
будет проходить через все это.
Я понимаю, что сжатые файлы не могут быть случайно доступны, и если я разрежу, пусть скажем последние 5 МБ, то данные сразу после разреза будут мусором - но может ли gzip повторно синхронизировать и декодировать остальную часть потока?
Если я правильно его понимаю, gzip stream - это простой поток команд, описывающих, что выводить - с ним можно было бы синхронизировать. Тогда есть 32kB скользящее окно из последних несжатых данных, которое начинается, как мусор, конечно, если мы начнем посередине, но я бы предположил, что он, как правило, быстро заполняется реальными данными, и с этого момента декомпрессия тривиальна (ну, возможно, что что-то повторяется снова и снова от начала файла до конца, и поэтому скользящее окно никогда не очищается - меня это удивило бы, если бы все было так часто, и если это произойдет, мы просто обработаем весь файл).
Я не страшно желаю сделать этот род gzip hackery сам - раньше никто не делал этого, чтобы иметь дело с поврежденными файлами, если ничего больше?
В качестве альтернативы - если gzip действительно не может этого сделать, могут ли быть какие-либо другие программы сжатия потока, которые очень похожи на него, за исключением того, что они позволяют повторно синхронизировать средние потоки?
EDIT: я нашел чистую Ruby reimplementation zlib и взломал ее, чтобы печатать возраст байтов в скользящем окне. Оказывается, что вещи многократно копируются и даже после 5 Мбайт + скользящее окно по-прежнему содержит вещи из первых 100 байт и из случайных мест по всему файлу.
Мы не можем даже обойти это, читая первые несколько блоков и последние несколько блоков, так как эти первые байты напрямую не ссылаются, это просто очень длинная цепочка копий, и единственный способ узнать, что он имеет в виду обрабатывает все это.
По сути, с настройками по умолчанию, что я хотел, возможно, невозможно.
С другой стороны, zlib имеет параметр Z_FULL_FLUSH
, который очищает это скользящее окно для синхронизации. Так что вопрос все еще стоит. Предполагая, что zlib синхронизирует время от времени, есть ли какие-либо инструменты для чтения только конца этого, не обрабатывая все это?
Z_FULL_FLUSH выдает известную последовательность байтов (00 00 FF FF), которую вы можете использовать для синхронизации. Эта ссылка может быть полезна.
В этом разница между блочными и потоковыми шифрами. Поскольку gzip - это потоковый шифр, вам может понадобиться весь файл до определенной точки для дешифрования байтов в этой точке.
Как вы говорите, когда окно очищается, вы золотые. Но нет никакой гарантии, что zlib на самом деле делает это достаточно часто для вас... Я предлагаю вам искать назад с конца файла и найти маркер для полной очистки.