Возможна ли частичная декомпрессия gz?

Для работы с изображениями, которые хранятся в виде файлов.gz (мое программное обеспечение для обработки изображений может считывать файлы.gz для более короткого / меньшего пространства / времени на диске), мне нужно проверить заголовок каждого файла.

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

Можно ли будет прочитать первый сегмент файла.gz (скажем, пару K), распаковать этот сегмент и прочитать исходное содержимое? Насколько я понимаю, gz заключается в том, что после некоторого начального учета сжатые данные сохраняются последовательно - это правильно?

так вместо
1. открыть большой файл F
2. распакуйте большой файл F
3. прочитать 500-байтовый заголовок
4. повторно сжать большой файл F

делать
1. открыть большой файл F
2. прочитать первые 5 K из F как поток A
3. распаковать A как поток B
4. прочитать 500-байтовый заголовок из B

я использую libz.so но решения на других языках приветствуются!

3 ответа

Решение

Ты можешь использовать gzip -cd file.gz | dd ibs=1024 count=10 например, распаковать только первые 10 КиБ.

gzip -cd распаковывает на стандартный вывод.

труба | это в dd полезность.

dd Утилита копирует стандартный ввод в стандартный вывод. Такdd ibs=1024 устанавливает размер входного блока в 1024 байта вместо 512 по умолчанию.

А также count=10 Копирует только 10 входных блоков, тем самым останавливая распаковку gzip.

Ты захочешь сделать gzip -cd file.gz | dd count=1 используя стандартный размер блока 512 и просто игнорировать дополнительные 12 байтов.

Комментарий выделяет, что вы можете использовать gzip -cd file.gz | head -c $((1024*10)) или в этом конкретном случае gzip -cd file.gz | head -c $(512), Комментарий к оригиналу dd полагается, что распаковка gzip в 1024 году не кажется верной. Например dd ibs=2 count=10 распаковывает первые 20 байтов.

Да, это возможно.

Но не изобретайте колесо, база данных HDF5 поддерживает разные алгоритмы сжатия (среди них gz), и вы можете обращаться к разным частям. Он совместим с Linux и Windows, и есть оболочки для многих языков. Он также поддерживает чтение и распаковку параллельно, что очень полезно, если вы используете высокую степень сжатия.

Вот сравнение скорости чтения с использованием различных алгоритмов сжатия от Python до PyTables:

участок

Поток Deflate может иметь несколько блоков вплотную. Но вы всегда можете распаковать только желаемое количество байтов, даже если оно является частью большего блока. Функция zlib gzread принимает аргумент длины, и существуют различные другие способы распаковки определенного количества байтов открытого текста, независимо от длины полного потока. Увидеть zlib руководство для списка функций и как их использовать.

Непонятно, хотите ли вы изменять только заголовки. (Вы упоминаете повторное сжатие всего файла, но опция B ничего не сжимает). Если это так, запишите заголовки в отдельный блок Deflate, чтобы вы могли заменить этот блок без повторного сжатия остальной части изображения. использование Z_FULL_FLUSH когда вы звоните в Zlib deflate Функция для записи заголовков. Вам, вероятно, не нужно записывать сжатую длину заголовков где-либо; Я думаю, что это может быть вычислено при чтении их, чтобы выяснить, какие байты заменить.

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

Другие вопросы по тегам