简体   繁体   中英

Trying to download a file from aws s3 into nodejs writeStream

I am trying to download a file from s3 and directly put into into a file on the filesystem using a writeStream in nodejs. This is my code:

downloadFile = function(bucketName, fileName, localFileName) {
    //Donwload the file
    var bucket = new AWS.S3({
        params: { Bucket: bucketName },
        signatureVersion: 'v4'
    });
    var file = require('fs').createWriteStream(localFileName);
    var request = bucket.getObject({ Key: fileName });
    request.createReadStream().pipe(file);
    request.send();
    return request.promise();
}

Running this function I get this error:

Uncaught Error: write after end

What is happening? Is the file closed before the write is finished? Why?

var s3 = new AWS.S3({
    accessKeyId: accessKeyId,
    secretAccessKey: secretAccessKey
}),
file = fs.createWriteStream(localFileName);
s3
.getObject({
    Bucket: bucketName,
    Key: fileName
})
.on('error', function (err) {
    console.log(err);
})
.on('httpData', function (chunk) {
    file.write(chunk);
})
.on('httpDone', function () {
    file.end();
})
.send();

Also AWS notes an example of using promises like this:

const s3 = new aws.S3({apiVersion: '2006-03-01'});
const params = { Bucket: 'yourBucket', Key: 'yourKey' };
const file = require('fs').createWriteStream('./local_file_path');

const s3Promise = s3.getObject(params).promise();

s3Promise.then((data) => {
  file.write(data.Body, () => {
    file.end();
    fooCallbackFunction();
  });
}).catch((err) => {
  console.log(err);
});

This works perfect for me.
https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/using-promises.html

EDIT: (15 Feb 2018) Updated the code, as you have to end the write stream ( file.end() ).

I have combined the above response with a typical gunzip operation in pipe:

            var s3DestFile = "./archive.gz";
            var s3UnzippedFile    = './deflated.csv';

            var gunzip = zlib.createGunzip();
            var file = fs.createWriteStream( s3DestFile );
            s3.getObject({ Bucket: Bucket, Key: Key })
            .on('error', function (err) {
                console.log(err);
            })
            .on('httpData', function (chunk) {
                file.write(chunk);
            })
            .on('httpDone', function () {
                file.end();

                console.log("downloaded file to" + s3DestFile);
                fs.createReadStream( s3DestFile )
                .on('error', console.error)
                .on('end', () => {
                    console.log("deflated to "+s3UnzippedFile)
                })
                .pipe(gunzip)
                .pipe(fs.createWriteStream( s3UnzippedFile ))
            })
            .send();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM