it-swarm.com.de

lesen Sie die Datei aus dem aws s3-Bucket mit dem Knoten fs

Ich versuche, eine Datei zu lesen, die sich in einem aws s3-Bucket befindet 

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

Ich konnte eine Datei mit dem Knoten aws-sdk herunterladen und hochladen, aber ich weiß nicht, wie ich sie einfach lesen und den Inhalt analysieren kann.

Hier ist ein Beispiel, wie ich die Datei von S3 lese:

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

Sie haben mehrere Möglichkeiten. Sie können einen Rückruf als zweites Argument einschließen, das mit einer Fehlermeldung und dem Objekt aufgerufen wird. Dieses Beispiel ist direkt aus der AWS-Dokumentation:

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

Alternativ können Sie die Ausgabe in einen Stream konvertieren. In der AWS-Dokumentation gibt es auch ein Beispiel :

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);
71
dug

Das wird es tun:

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

Da Sie scheinbar eine S3-Textdatei zeilenweise bearbeiten wollen. Hier ist eine Node-Version, die das Standard-Readline-Modul und createReadStream () von AWS verwendet.

const readline = require('readline');

const rl = readline.createInterface({
    input: s3.getObject(params).createReadStream()
});

rl.on('line', function(line) {
    console.log(line);
})
.on('close', function() {
});
18
Jason

Ich konnte noch nicht verstehen warum, aber die createReadStream/pipe-Methode funktionierte nicht für mich. Ich habe versucht, eine große CSV-Datei (300 MB +) herunterzuladen, und erhielt doppelte Zeilen. Es schien ein zufälliges Problem zu sein. Die endgültige Dateigröße variiert bei jedem Download-Versuch.

Am Ende habe ich einen anderen Weg gewählt, basierend auf AWS JS SDK-Beispielen :

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

Auf diese Weise funktionierte es wie ein Zauber.

6
Gustavo Straube

hier ist das Beispiel, mit dem ich Json-Daten von S3 abgerufen und analysiert hat. 

    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
           ......
     }
   });
4
devendra

Wenn Sie Speicherplatz sparen und jede Zeile als Json-Objekt abrufen möchten, können Sie mit fast-csv den Readstream erstellen und jede Zeile als Json-Objekt wie folgt lesen:

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');
});
2
kgangadhar

Ich hatte genau das gleiche Problem beim Herunterladen von sehr großen Dateien aus S3.

Die Beispiellösung aus AWS-Dokumenten funktioniert einfach nicht:

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

Diese Lösung funktioniert zwar:

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

Der createReadStream-Versuch löst aus irgendeinem Grund einfach den Callback end, close oder error nicht aus. hier darüber.

Ich verwende diese Lösung auch, um Archive in gzip aufzuschreiben, da die erste (AWS-Beispiel) in diesem Fall auch nicht funktioniert:

        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();
2
loretoparisi

Ich bevorzugeBuffer.from(data.Body).toString('utf8'). Es unterstützt Codierungsparameter. Bei anderen AWS-Diensten (z. B. Kinesis Streams) möchte jemand die 'utf8'-Kodierung durch 'base64' ersetzen.

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