我在大型zip文件的下载流中找到了local file header
的结尾
deflate
压缩
,现在想使用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
嗯,看起来好像已经设置了节点,以将解压缩的缓冲区作为一个块返回给回调;看起来好像没有设置node来确定deflate流的末尾。
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库解压缩,那么该库很有可能会这样做。我认为,要正确执行此操作,需要从zlib API文档中获取:https://zlib.net/manual.html
Z_BLOCK选项有助于附加或组合放气流。为了解决这个问题,在返回时,inflate()始终将strm-> data_type设置为从strm-> next_in获取的最后一个字节中未使用的位数,如果inflate()当前正在解码deflate流中的最后一个块,则将其设置为64,如果在解码完块结束代码或解码完整的标头之后紧接着在deflate流的第一个字节之前返回inflate(),则返回128。在该块的所有未压缩数据都已写入strm-> next_out之前,不会指示该块的末尾。除了设置data_type的位7时,未使用的位数通常可以大于七个,在这种情况下,未使用的位数将小于八个。每次为所有刷新选项返回inflate()时,都会按此处所述设置data_type,因此可用于确定当前消耗的输入量(以位为单位)。
这似乎表明最终的压缩位将不按字节对齐。但是ZIP规范似乎表明标头以魔术sig开头,每个人都在使用但不应该这样,标头是按字节对齐的:https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
4.3.9.1如果通用的第3位,则该描述符必须存在 目的位标志已设置(请参见下文)。 它是字节对齐的 并紧随压缩数据的最后一个字节。 仅当无法执行此描述符时,才应使用 在输出.ZIP文件中查找,例如,在输出.ZIP文件时 是标准输出或不可搜索的设备。对于ZIP64(tm)格式 档案,压缩和未压缩的大小均为8个字节。
如何将deflate流的末尾不按字节对齐,而将后面的数据描述符按字节对齐?
有很好的参考实现吗?
将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
,就无法压缩zip。我不知道为什么会这样。流描述了它们的长度...并且Mark验证了它们是否可以流化。
而here是Node.js检查Z_STREAM_END
的地方!
答案 0 :(得分:0)
看起来像这样,因为文档列出了zlib.constants.Z_STREAM_END
作为可能的返回值。