节点zlib增量膨胀

问题描述 投票:0回答:1

我在一个大型zip文件的下载流中找到了local file header的结尾

  • 指定deflate压缩
  • 第3位设置表示压缩数据的长度跟随压缩数据

并且现在想使用Node zlib来扩充该数据,但我无法弄清楚如何将数据提供给zlib并接收反馈,告诉我什么时候deflate流已经自我终止。

Node的zlib库是否支持消耗大量的deflate数据并返回一个结果,让调用者知道deflate流何时结束?

或者这是一件疯狂的事情,因为它意味着我在UI线程上膨胀,我应该做的是保存下载的文件,一旦下载使用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_callbackThe 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 lib解压缩,那么lib很可能正在这样做。我认为,要做到这一点,需要从zlib API文档中克服这个问题:https://zlib.net/manual.html

Z_BLOCK选项有助于附加或组合deflate流。为了协助这一点,在返回时inflate()总是将strm-> data_type设置为从strm-> next_in取得的最后一个字节中的未使用位数,如果inflate()正在解码deflate流中的最后一个块,则加64。如果在解码块结束代码之后立即返回inflate(),或者将完整标头解码到deflate流的第一个字节之前,则加上128。在将来自该块的所有未压缩数据写入strm-> next_out之前,不会指示块结束。未使用的位的数量通常可以大于7,除非设置了data_type的位7,在这种情况下,未使用的位的数量将小于8。每次inflate()返回所有刷新选项时,data_type的设置如此处所示,因此可用于确定当前消耗的输入量(以位为单位)。

这似乎表明最终的压缩位不是字节对齐的。然而ZIP规范似乎表明以魔法sig开头的标题,每个人都在使用但不应该使用字节对齐:https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT

4.3.9.1如果设置了通用位标志的第3位,则该描述符必须存在(见下文)。它是字节对齐的,紧跟在压缩数据的最后一个字节之后。只有在无法在输出.ZIP文件中搜索时,例如,当输出.ZIP文件是标准输出或不可搜索的设备时,才应该使用该描述符。对于ZIP64(tm)格式存档,压缩和未压缩的大小各为8个字节。

如何将deflate流的结尾不进行字节对齐,但后面的数据描述符是字节对齐的?

有一个很好的参考实现?


使用带有Z_BLOCK的膨胀参考impl: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

我不明白为什么会这样。流描述了它们的长度...... Mark确认它们可以流式传输。


here是Node.js检查Z_STREAM_END的地方!

node.js zip zlib zipfile nodejs-stream
1个回答
0
投票

看起来确实如此,因为文档将zlib.constants.Z_STREAM_END列为可能的返回值。

© www.soinside.com 2019 - 2024. All rights reserved.