web-dev-qa-db-ja.com

部分ファイルをガンジッピングするときに、zlibの「予期しないファイルの終わり」を回避するにはどうすればよいですか?

Gzipで圧縮されたファイルの一部を解凍しながら読み取ろうとしているので、不要なバイトを読み取らずにヘッダーの内容を解析できます。以前はfs.read()を使用してこれを機能させ、オプションを渡して最初の500バイトのみを読み取り、次にzlib.gunzip()を使用してコンテンツを解凍してから、バイナリデータからヘッダーを解析しました。

これは、ノード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()関数は正しいヘッダーコンテンツを返しているので、解凍していることはわかっていますが、入力の最後に到達するとエラーがスローされます。エラーを処理するためにエラーリスナーを追加して何もしないことはできますが、これは理想的ではないようです。

何か案は?

8
Constellates

すべての提案をありがとう。また、ノードリポジトリに質問の問題を送信し、いくつかの良いフィードバックを得ました。これが私のために働いた結果です。

  • チャンクサイズを完全なヘッダーサイズに設定します。
  • 単一のチャンクを解凍ストリームに書き込み、すぐにストリームを一時停止します。
  • 解凍されたチャンクを処理します。

var bytesRead = 500;
var decompressStream = zlib.createGunzip()
    .on('data', function (chunk) {
        parseHeader(chunk);
        decompressStream.pause();
    }).on('error', function(err) {
        handleGunzipError(err, file, chunk);
    });

fs.createReadStream(file.path, {start: 0, end: bytesRead, chunkSize: bytesRead + 1})
    .on('data', function (chunk) {
        decompressStream.write(chunk);
    });

これはこれまで機能しており、pause()によって解凍ストリームが「予期しないファイルの終わり」エラーをスローするのを防ぐため、他のすべてのgunzipエラーを処理し続けることができます。

6
Constellates