やろうとしたこと
タイトルの通り、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のイベントとして決まっており、当然何でも良いわけではない。
Node.jsのStreamは非常に便利なのでPromise(async / await)も併せてどんどん使っていきたい。