LoginSignup
4
5

More than 5 years have passed since last update.

node.jsでパイプを使ってパスワードつきZIPを解凍する

Last updated at Posted at 2015-11-19

※*nuxなどfunzipが叩ける前提で

パスワードつきZIPファイルが添付されたメールを受け取り、添付ファイルをゴニョゴニョとやりたいことがありまして
メールからZIPファイルを取り出すとこまではMailParserでアッサリと書けたのですが、node.jsのみで完結してパスワードつきZIPファイルを解凍するという方法が見つからなくてですね

*nixにだいたいあるunzipコマンドは入力に標準入力がとれないことが多いです
テンポラリファイルに書き込んで処理するというのもディスクへの入出力を余計にはさまないといけないのがいまいちダサい気がしまして

調べたらunzipの標準入力・標準出力専門版みたいなfunzipというコマンドがあるらしいので、それを使ってみましょう

ついでにBufferに入ったデータを他プロセスのstdinに流し込んで、その標準出力をキャプチャするという例にもなってます

funzipコマンドをパスが通っているところにインストールした上でお試しください

var fs = require('fs');
var ZIP_FILE = 'ZIPファイルの在処';

var spawn = require('child_process').spawn;
var stream = require('stream');
var ZIP_PASSWORD = 'ZIPファイルのパスワード';
var FUNZIP_OPTIONS  = '-' + ZIP_PASSWORD;

var funzip = spawn('funzip', [FUNZIP_OPTIONS]);
var chunks = [];

funzip.stdout.on('data', function(chunk){
    chunks.push(chunk);
});


/**
*    解凍結果を処理するのがここ
*/
funzip.stdout.on('close', function(){
    var buffer = Buffer.concat(chunks);
    /**
    *   この時点でbufferはバイナリのBufferになってますので適宜
    *   処理してね
    */
});

/**
*   例としてファイルからZIPファイルを読み込んでますが
*/
fs.readFile(ZIP_FILE, 'binary', function(err, data){
    /**
    *   Bufferになっているdataを処理するなら流れは同じ
    */
    var bufferStream = new stream.PassThrough();
    bufferStream.end(new Buffer(data, 'binary'));
    /**
    *   ↓でfunzipコマンドのstdinにdataを流し込んでます
    *   $ funzip < data みたいな感じです
    */
    bufferStream.pipe(funzip.stdin);
});
4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5