node getobject aws node.js amazon-web-services amazon-s3 fs

node.js - getobject - leer el archivo del aws s3 bucket usando el nodo fs



aws sdk uuid (8)

Aquí está el ejemplo que utilicé para recuperar y analizar datos json de s3.

var params = {Bucket: BUCKET_NAME, Key: KEY_NAME}; new AWS.S3().getObject(params, function(err, json_data) { if (!err) { var json = JSON.parse(new Buffer(json_data.Body).toString("utf8")); // PROCESS JSON DATA ...... } });

Estoy intentando leer un archivo que está en un bucket aws s3 usando

fs.readFile(file, function (err, contents) { var myLines = contents.Body.toString().split(''/n'') })

He podido descargar y cargar un archivo usando el nodo aws-sdk, pero no sé cómo leerlo y analizar el contenido.

Aquí hay un ejemplo de cómo estoy leyendo el archivo de s3:

var s3 = new AWS.S3(); var params = {Bucket: ''myBucket'', Key: ''myKey.csv''} var s3file = s3.getObject(params)


Esto lo hará:

new AWS.S3().getObject({ Bucket: this.awsBucketName, Key: keyName }, function(err, data) { if (!err) console.log(data.Body.toString()); });


Prefiero Buffer.from(data.Body).toString(''utf8'') . Soporta parámetros de codificación. Con otros servicios de AWS (por ejemplo, Kinesis Streams), alguien puede querer reemplazar ''utf8'' codificación ''utf8'' con ''base64'' .

new AWS.S3().getObject( { Bucket: this.awsBucketName, Key: keyName }, function(err, data) { if (!err) { const body = Buffer.from(data.Body).toString(''utf8''); console.log(body); } } );


Si desea ahorrar memoria y desea obtener cada fila como un objeto json, puede usar fast-csv para crear un flujo de lectura y puede leer cada fila como un objeto json de la siguiente manera:

const csv = require(''fast-csv''); const AWS = require(''aws-sdk''); const credentials = new AWS.Credentials("ACCESSKEY", "SECRETEKEY", "SESSIONTOKEN"); AWS.config.update({ credentials: credentials, // credentials required for local execution region: ''your_region'' }); const dynamoS3Bucket = new AWS.S3(); const stream = dynamoS3Bucket.getObject({ Bucket: ''your_bucket'', Key: ''example.csv'' }).createReadStream(); var parser = csv.fromStream(stream, { headers: true }).on("data", function (data) { parser.pause(); //can pause reading using this at a particular row parser.resume(); // to continue reading console.log(data); }).on("end", function () { console.log(''process finished''); });


Todavía no podía entender por qué, pero el enfoque createReadStream / pipe no funcionó para mí. Intenté descargar un archivo CSV grande (300MB +) y obtuve líneas duplicadas. Parecía un problema al azar. El tamaño final del archivo varió en cada intento de descargarlo.

Terminé usando otra forma, basada en ejemplos de AWS JS SDK :

var s3 = new AWS.S3(); var params = {Bucket: ''myBucket'', Key: ''myImageFile.jpg''}; var file = require(''fs'').createWriteStream(''/path/to/file.jpg''); s3.getObject(params). on(''httpData'', function(chunk) { file.write(chunk); }). on(''httpDone'', function() { file.end(); }). send();

De esta manera, funcionó a las mil maravillas.


Tuve exactamente el mismo problema al descargar desde S3 archivos muy grandes.

La solución de ejemplo de los documentos de AWS simplemente no funciona:

var file = fs.createWriteStream(options.filePath); file.on(''close'', function(){ if(self.logger) self.logger.info("S3Dataset file download saved to %s", options.filePath ); return callback(null,done); }); s3.getObject({ Key: documentKey }).createReadStream().on(''error'', function(err) { if(self.logger) self.logger.error("S3Dataset download error key:%s error:%@", options.fileName, error); return callback(error); }).pipe(file);

Si bien esta solución funcionará:

var file = fs.createWriteStream(options.filePath); s3.getObject({ Bucket: this._options.s3.Bucket, Key: documentKey }) .on(''error'', function(err) { if(self.logger) self.logger.error("S3Dataset download error key:%s error:%@", options.fileName, error); return callback(error); }) .on(''httpData'', function(chunk) { file.write(chunk); }) .on(''httpDone'', function() { file.end(); if(self.logger) self.logger.info("S3Dataset file download saved to %s", options.filePath ); return callback(null,done); }) .send();

El intento de createReadStream simplemente no dispara el end , close o devolución de llamada de error por alguna razón. Mira here sobre esto.

Estoy usando esa solución también para escribir archivos en gzip, ya que el primero (ejemplo de AWS) tampoco funciona en este caso:

var gunzip = zlib.createGunzip(); var file = fs.createWriteStream( options.filePath ); s3.getObject({ Bucket: this._options.s3.Bucket, Key: documentKey }) .on(''error'', function (error) { if(self.logger) self.logger.error("%@",error); return callback(error); }) .on(''httpData'', function (chunk) { file.write(chunk); }) .on(''httpDone'', function () { file.end(); if(self.logger) self.logger.info("downloadArchive downloaded %s", options.filePath); fs.createReadStream( options.filePath ) .on(''error'', (error) => { return callback(error); }) .on(''end'', () => { if(self.logger) self.logger.info("downloadArchive unarchived %s", options.fileDest); return callback(null, options.fileDest); }) .pipe(gunzip) .pipe(fs.createWriteStream(options.fileDest)) }) .send();


Usted tiene un par de opciones. Puede incluir una devolución de llamada como segundo argumento, que se invocará con cualquier mensaje de error y el objeto. Este example proviene directamente de la documentación de AWS:

s3.getObject(params, function(err, data) { if (err) console.log(err, err.stack); // an error occurred else console.log(data); // successful response });

Alternativamente, puede convertir la salida a una secuencia. También hay un example en la documentación de AWS:

var s3 = new AWS.S3({apiVersion: ''2006-03-01''}); var params = {Bucket: ''myBucket'', Key: ''myImageFile.jpg''}; var file = require(''fs'').createWriteStream(''/path/to/file.jpg''); s3.getObject(params).createReadStream().pipe(file);


Ya que parece querer procesar un archivo de texto S3 línea por línea. Aquí hay una versión de nodo que utiliza el módulo de línea de lectura estándar y el archivo createReadStream de AWS

const readline = require(''readline''); const rl = readline.createInterface({ input: s3.getObject(params).createReadStream() }); rl.on(''line'', function(line) { console.log(line); }) .on(''close'', function() { });