Node.jsでダウンロードしながらGunzipしてmd5の計算しながら保存する奴

nodejs zlib gunzip crypto md5 http
0 Comments
Tweet

Node.jsです。
Lempel-Ziv符号化で圧縮されたファイル(.gz)のダウンロードをしようとしたときの話です。
ブラウザからダウンロードすると、拡張子gzで保存され、それを解凍することで必要なデータを得ることができるのですが、圧縮されたファイルは解凍したあとでは不要です。
このような不要ファイルを保存することなく、目的のファイルが欲しいような状況になったので、いろいろと調べて解決しました。

Lempel-Ziv符号化で圧縮されたファイルは、かの有名なzlibによって扱うことができます。
Node.jsの標準モジュールには、zlibがあり、require()で取り込むことでzlibを利用することができます。
標準モジュールであるため、APIに関する説明がNode.js公式ドキュメントにあるのですが、よく使い方がわからなかったので、いろいろと試行錯誤してみました。

結果、zlibモジュールを利用してストリームを扱うオブジェクトを作成し、パイプでつなげることで、前途の目的である、圧縮されたアーカイブファイルを保存することなく、目的のファイルを保存することができました。

以下、ソースコードになります。
引数に拡張子gzのファイルのURLを渡し実行することで、解凍されたファイルを保存できます。

20行目のres.pipe(gunzip).pipe(output);にてhttp.getで得られたストリームをzlib.createGunzip()で作成したgunzipオブジェクトにパイプで渡し、処理されたものを、fs.createWriteStream()で作成されたoutputオブジェクトにさらにパイプすることで不要なファイルを保存することなく、ダウンロードしながら解凍し、保存しています。

保存時に、gunzipオブジェクトの’data’イベントを拾って、crypto標準モジュールでmd5の値を計算させています。
ダウンロードのときはmd5チェックしたいですし。

Node.jsのzlibモジュールに関して、あまり実例がなく、せっかくなので記事にしました。
ご参考になれば幸いです。