Получить сжатый размер байта после zlib_decode ()?

Я пытаюсь использовать PHP для анализа пользовательского формата файла архива gzip, который был создан в Delphi (не мой код!). Формат в основном:

4-byte integer: count of files in archive

for each compressed file:
4-byte integer: filename length [n]
[n] bytes: filename
4-byte integer: uncompressed file length [m]
[????] bytes: gzipped content

Я могу прочитать файл и правильно декодировать первый сжатый файл, используя zlib_decode () с максимальной несжатой длиной [м] байтов в оставшейся части файла после того, как я знаю длину ([м]), но затем я застрял, потому что я не знаю, как далеко в подстроке я должен идти, чтобы найти следующее имя файла — zlib_decode () не возвращает количество сжатых байтов, обработанных перед остановкой. Так как это пользовательский формат, не похоже, что я могу использовать обычный gzopen ()/gzread () функции, потому что весь файл не сжат (я пытался, это не работает).

Этот код работает в Delphi, потому что, очевидно, вы можете передавать дескриптор файла назад и вперед между обычными функциями чтения файлов и функциями декодирования System.ZLib — вы можете прочитать [m] несжатых байтов, и указатель останется на последнем сжатом байте — но PHP, кажется, не поддерживает переключение между чтением как обычно и чтением как gzip на лету таким образом.

Я пропускаю очевидный способ в PHP иметь дело с форматом файла со смешанным содержимым, таким как метаданные и сжатые данные, объединенные таким образом? Или мне не повезло, не зная длины сжатых данных?

2

Решение

Грязный обходной путь заключается в том, чтобы повторно сжать содержимое каждого файла, поскольку я могу его проанализировать, использовать его для вычисления сжатой длины и вручную настроить указатель файла в исходном файле следующим образом:

$current_pos = ftell($handle);
$skip_length = strlen(gzencode($uncompressed_text,9,FORCE_DEFLATE));
fseek($handle, $skip_length+$current_pos);

Это работает, но кажется очень взломанным. Я все еще был бы открыт для любых лучших подходов.

РЕДАКТИРОВАТЬ:

Просто обратите внимание, что это в конечном итоге не удалось. Тем не менее, мне посчастливилось знать заранее список ожидаемых имен файлов, и я смог сделать следующее (более надежно, поскольку zlib_decode () будет декодировать столько, сколько сможет, и в любом случае отбросит остальные):

foreach ($filenames as $thisFilename) {
$thisPos = strpos($rawData, $thisFilename);
$gzresult = zlib_decode(substr($rawData, $thisPos + strlen($table) + 8)); // skip 8 bytes for filename size and uncompressed data size, which are useless info.
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector