のーずいだんぷ

主に自分用メモですが、もしかしたら誰かの役に立つかもしれません

<Node.js>ストリームでgzip圧縮する方法とpipeでのエラーハンドリングについて

やろうとしたこと

タイトルの通り、Node.jsでgzip圧縮する方法を調べたが、意外と調べてもいい情報が見つからなかったのでまとめておく。 方法は2種類あり、

  • 同期的な圧縮
  • 非同期的な圧縮

が存在する。圧縮は時間のかかる処理であるため、通常は後者の非同期的な圧縮を行う。 非同期的な圧縮にはストリームを使用して、pipeによるエラーハンドリングも行う。 あと、処理自体は関数でラップし、その型はPromise型で返すことを目標とした。

実際のコード

// importするライブラリ
let fs = require('fs');
let zlib = require('zlib');

// 各Stream作成
var inStream = fs.createReadStream('test_file.txt')
var outStream = fs.createWriteStream('test_file.txt.gz')
var gzipstream = zlib.createGzip();

// gzip関数定義
function gzipComplessor(ins, outs, gzips){
  return new Promise(function(resolve, reject){
    ins.on('error', function(e){
      console.log('error, when create input stream.'}));
      reject(e)
    })
        .pipe(gzips)
        .on('error', function(e){
          console.log('error, when transform use by gzip compressor'}));
          reject(e)
        })
        .pipe(outs)
        .on('error', function(e){
          console.log('error, when create output stream'}));
          reject(e)
        })
        .on('finish', function(){
          console.log('Succeeded to compression process'}));
          resolve()
        })

  })
}

gzipCompressor(inStream, outStream, gzipStream)
.then(function(date){ ... })    //resolve()の処理 
.catch(function(err){ ... })    //reject()の処理

解説

基本的は以下のような流れの処理となっている。


inputStream

変換を行うStream(圧縮、暗号化等)

outputStream


上記のStream間を.onでつないでいるのはエラー処理のためである。 pipe処理の場合、各pipe直前のエラーしか拾うことができないので、例のようにonメソッドを配置する必要があるようだ。 今回のようにinputとoutputまでエラーハンドリングがいるかと問われると正直微妙なところだが、例えば複数の変換Streamを使用する場合は使う意味があるだろう。

また、Streamに慣れていない人は.on('error').on('finish')の中身は何かと思うかもしれない。 これはStreamAPIのイベントとして決まっており、当然何でも良いわけではない。

nodejs.org

Node.jsのStreamは非常に便利なのでPromise(async / await)も併せてどんどん使っていきたい。

参考

stackoverflow.com

stackoverflow.com