2016-09-11 11 views
2

私はファイルを(S3からBufferとして返されます)、それをストリームから解凍して、/tmp/fooにディスクに保存しようとしています。ファイルに保存するノード、バッファ、

untar(zlib.gunzip())関数をこのスクリプトが一度に1つのファイルしか処理しない場合、非同期に処理することは重要ですか?ストリームを使って何を得なければなりませんか?

var getS3Args = { bucket: 'foo', key: 'bar.tar.gz' } 

lib.getS3Object(getS3Args, function(getS3ObjectResponse) { 
    zlib.gunzip(getS3ObjectResponse.Body, function(err, result) { 
    if(err) return console.error(err); 

    // ? 

    console.log(result); 
    return callback(result); 
    }); 
}); 

答えて

3

S3のデータストリームは、aws-sdkから直接取得できます。ストリームを使用する際に得られる利点は、バッファ全体をメモリ上で操作する必要がないため、メモリの使用量が大幅に減ることです。ストリームは一度に小さなチャンクで動作し、その後、それらのチャンクは処理された後にガベージコレクションされます。現在の方法を使用して、S3から1TBブロブをダウンロードする場合は、バッファ全体をメモリに収める方法がないため、メモリ不足エラーが発生する可能性があります。ストリームを使用する場合、チャンクはHTTPレスポンスから降りてくるので、チャンクは解凍され、解凍され、ファイルシステムに単独で書き込まれますHTTPレスポンス全体に対して

var AWS = require('aws-sdk') 
var S3 = new AWS.S3() 
var fs = require('fs') 
var tar = require('tar') 
var zlib = require('zlib') 
var path = require('path') 
var mkdirp = require('mkdirp') 
var getS3Args = { bucket: 'foo', key: 'bar.tar.gz' } 
var dest = '/path/to/destination' 

S3.getObject(getS3Args) 
    .createReadStream() 
    .pipe(zlib.Unzip()) 
    .pipe(tar.Parse()) 
    .on('entry', function(entry) { 
    var isDir  = 'Directory' === entry.type 
    var fullpath = path.join(dest, entry.path) 
    var directory = isDir ? fullpath : path.dirname(fullpath) 
    mkdirp(directory, function(err) { 
     if (err) throw err 
     if (!isDir) entry.pipe(fs.createWriteStream(fullpath)) 
    }) 
    }) 
関連する問題