2016-09-11 4 views
2

Ich versuche, eine Datei (zurückgegeben als Buffer von S3), entpacken Sie es (das ist ein Stream), und speichern Sie es dann auf der Festplatte unter /tmp/foo.Knoten, Puffer, zum Streamen, zum Speichern in einer Datei

Ist es überhaupt von Bedeutung, ob ich die Funktion untar (zlib.gunzip()) asynchron handhabe, wenn dieses Skript immer nur eine Datei gleichzeitig behandelt. Was muss ich durch die Verwendung von Streams erreichen?

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); 
    }); 
}); 

Antwort

3

Sie können einen Strom der Daten in S3 direkt von der AWS-SDK erhalten. Der Vorteil, den Sie bei der Verwendung von Streams haben, ist, dass sie viel weniger Speicher benötigt, da nicht der gesamte Pufferspeicher benötigt wird, um damit zu arbeiten. Streams arbeiten jeweils auf kleinen Stücken und dann werden diese Stückchen nach der Verarbeitung mit Müll gesammelt. Wenn Sie mit der aktuellen Methode ein 1TB-Blob von S3 herunterladen möchten, erhalten Sie wahrscheinlich einen Fehler wegen zu wenig Arbeitsspeicher, da Sie den gesamten Puffer nicht im Speicher unterbringen können. Bei der Verwendung von Streams würden Sie wahrscheinlich nie mehr als ein paar zusätzliche MB an Speicher sehen, da ein Chunk aus der HTTP-Antwort kommt. Dieser Chunk würde dann entpackt, entpackt und von alleine in Ihr Dateisystem geschrieben, ohne warten zu müssen für die gesamte HTTP-Antwort.

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)) 
    }) 
    }) 
Verwandte Themen