Узел zlib инкрементальный надувать - PullRequest
0 голосов
/ 26 февраля 2019

Я нашел конец local file header в потоке загрузки большого zip-файла, который

  • указывает deflate сжатие с
  • битом 3, указывающим длинусжатых данных следует за сжатыми данными

и хотел бы теперь раздувать эти данные с помощью Node zlib, но я не могу понять, как передать данные в zlib и получить обратную связь, сообщающую мне, когда поток дефлирования сампрекращается.

Поддерживает ли библиотека zlib в Node потребление кусков дефлированных данных и возвращение результата, сообщая вызывающей стороне о завершении потока дефлирования?

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

Тем не менее, для моего назидания я все еще хотел бы знать, поддерживает ли Node потоковую инфляцию.

var zlib = require('zlib')
var data = bufferOfChunkOfDeflatedData
var inflate = zlib.createInflate();
var stream = inflate.pipe(fs.createWriteStream(path));
var result = stream.write(data);
// but result doesn't indicate if the inflate stream has terminated...

Описывает заголовки deflate и как они кодируют длину потока: https://www.bolet.org/~pornin/deflate-flush-fr.html


В потоке памяти: https://www.npmjs.com/package/memory-streams


Ну, этот парень просто тянет, пока не доберется до волшебной подписи!:) https://github.com/EvanOxfeld/node-unzip/blob/5a62ecbcef6523708bb8b37decaf6e41728ac7fc/lib/parse.js#L152


Код узла для настройки удобного метода: https://github.com/nodejs/node/blob/6e56771f2a9707ddf769358a4338224296a6b5fe/lib/zlib.js#L83 В частности: https://nodejs.org/api/zlib.html#zlib_zlib_inflateraw_buffer_options_callback


Э, похоже, узел настроен для возвратараспакованный буфер как один блок для обратного вызова;Не похоже, что узел настроен для определения конца потока дефляции.

https://nodejs.org/api/stream.html#stream_transform_transform_chunk_encoding_callback говорит The callback function must be called only when the current chunk is completely consumed. и вот место, где он передает кусок в zlib https://github.com/nodejs/node/blob/6e56771f2a9707ddf769358a4338224296a6b5fe/lib/zlib.js#L358. Так что нет никакой возможности сказать, что поток был частично использован ..


Но опять же ... https://github.com/ZJONSSON/node-unzipper/blob/affbf89b54b121e85dcd31adf7b1dfde58afebb7/lib/parse.js#L161 но не совсем.Также просто проверяет наличие магического сигнала: https://github.com/ZJONSSON/node-unzipper/blob/affbf89b54b121e85dcd31adf7b1dfde58afebb7/lib/parse.js#L153


И из спецификации zip:

4.3.9.3 Хотя изначально подпись не назначена, значение 0x08074b50 обычнобыл принят в качестве значения подписи для записи дескриптора данных.Разработчики ДОЛЖНЫ знать, что ZIP-файлы МОГУТ встречаться с или без этих дескрипторов данных для маркировки подписи, и ДОЛЖНЫ иметь учетную запись в любом случае при чтении ZIP-файлов для обеспечения совместимости.,


Марк говорит, что нет-нет ... Так что не делай этого.И знайте, что если вы используете библиотеку NPM для распаковки, то есть большая вероятность, что библиотека делает это.Чтобы сделать это правильно, я думаю, что нужно извлечь это из документации по API zlib: https://zlib.net/manual.html

Опция Z_BLOCK помогает добавлять или объединять потоки дефляции.Чтобы помочь в этом, при возврате inflate () всегда устанавливает strm-> data_type в число неиспользованных битов в последнем байте, взятом из strm-> next_in, плюс 64, если inflate () в настоящее время декодирует последний блок в потоке deflate,плюс 128, если inflate () возвращается сразу после декодирования кода конца блока или декодирования полного заголовка вплоть до первого байта потока deflate.Конец блока не будет указан, пока все несжатые данные из этого блока не будут записаны в strm-> next_out.Количество неиспользуемых битов в общем случае может быть больше семи, за исключением случая, когда установлен бит 7 типа data_type, и в этом случае количество неиспользуемых битов будет меньше восьми.Тип data_type устанавливается так, как указано здесь каждый раз, когда inflate () возвращает все параметры сброса, и поэтому может использоваться для определения количества потребляемого в настоящее время ввода в битах.

Это указывает на то, что последний сжатый бит не будет выровнен по байту.Тем не менее, спецификация ZIP, похоже, указывает, что заголовок, который начинается с волшебного сигма, тот, который каждый использует, но не должен, выровнен по байту: https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT

4.3.9.1 Этот дескриптор ДОЛЖЕН существовать, если бит3 битового флага общего назначения установлен (см. Ниже). Он выровнен по байту и сразу следует за последним байтом сжатых данных.Этот дескриптор ДОЛЖЕН использоваться только в том случае, если поиск выходного файла .ZIP невозможен, например, когда выходной файл .ZIP был стандартным выходным устройством или устройством без возможности поиска.Для архивов формата ZIP64 (tm) сжатый и несжатый размеры составляют 8 байтов каждый.

Как конец потока дефлятирования не может быть выровнен по байту, но следующий дескриптор данных может быть выровнен по байту?

Есть ли хорошая реализация ссылок?


Использование ссылок с использованием Inflate с Z_BLOCK: https://github.com/madler/zlib/blob/master/examples/gzappend.c


Этот парень читает в обратном направлении, чтобы вытащить каталог: https://github.com/antelle/node-stream-zip/blob/907c8876e8aeed6c33a668bbd06a0f79e7a022ef/node_stream_zip.js#L180 Это необходимо?

Этот парень, кажется, думает, что почтовые индексы невозможно раздуть, не прочитав весь файл, чтобы попасть в каталог: https://www.npmjs.com/package/yauzl#no-streaming-unzip-api

Я надеваюне понимаю, почему это так.Потоки описывают их длину ... и Марк проверяет, что они могут быть переданы в потоковом режиме.


И здесь - это где Node.js проверяет наличие Z_STREAM_END!

1 Ответ

0 голосов
/ 26 февраля 2019

Похоже, что так и есть, поскольку в документации указано zlib.constants.Z_STREAM_END в качестве возможного возвращаемого значения.

...