【发布时间】:2016-02-28 20:39:10
【问题描述】:
我正在尝试在解压缩 gzip 文件时读取它的一部分,这样我就可以在不读取不必要字节的情况下解析标头内容。我之前使用 fs.read() 进行了这项工作,同时传递选项以仅读取前 500 个字节,然后使用 zlib.gunzip() 在从二进制数据中解析标头之前解压缩内容。
在 node v5.0.0 修补了一个错误以确保 zlib 在截断的输入 (https://github.com/nodejs/node/pull/2595) 上引发错误之前,这一直运行良好。
现在我从 zlib 收到以下错误。
Error: unexpected end of file
如果知道我正在截断输入而不会引发错误,我该如何解压缩这个部分文件。我想用流可能会更容易,所以我写了以下内容。
var readStream = fs.createReadStream(file.path, {start: 0, end: 500});
var gunzip = zlib.createGunzip();
readStream.pipe(gunzip)
.on('data', function(chunk) {
console.log(parseBinaryHeader(chunk));
console.log('got %d bytes of data', chunk.length);
})
.on('error', function (err) {
console.log(err);
})
.on('end', function() {
console.log('end');
});
我的parseBinaryHeader() 函数正在返回正确的标头内容,所以我知道它正在解压缩,但是当它到达输入末尾时仍然会抛出错误。我可以添加错误侦听器来处理错误并且什么都不做,但这似乎并不理想。
有什么想法吗?
【问题讨论】:
-
不要输入截断的文件?它应该警告您输入基本上已损坏。
-
那么我如何才能解决需要有效读取一堆文件的标题而不关心其余内容的更大问题。文件数量和大小各不相同,但我通常会阅读 30 多个文件,总大小为 2-5GB。我只需要每个文件的前 500 个字节。我尝试完整阅读每个文件,但性能差异非常显着。
-
尝试/捕捉错误?除非 zlib 有一个可以启用的“忽略错误”标志,否则你会被它会吐出的东西所困扰,或者可以只编写自己的解压缩库。
-
可以不用流直接使用
zlib.createGunzip或zlib.createGunzipSync吗?您应该能够为其提供部分压缩数据和可用的未压缩数据。一旦你得到了你想要的东西,就杀死这些物体。 -
感谢@MarkAdler。我做了与此非常相似的事情。我将一个块写入 Gunzip 流,然后立即暂停流以避免文件意外结束。这使我能够继续处理所有其他 gunzip 错误。