Возможна ли частичная декомпрессия 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
Функция для записи заголовков. Вам, вероятно, не нужно записывать сжатую длину заголовков где-либо; Я думаю, что это может быть вычислено при чтении их, чтобы выяснить, какие байты заменить.
Если вы ничего не изменяете, повторное сжатие всего файла не имеет смысла. Вы можете искать и перезапускать декомпрессию с самого начала, найдя нужные вам заголовки...