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 soll.
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)
Antworten:
Sie haben ein paar Möglichkeiten. Sie können einen Rückruf als zweites Argument einfügen, das mit jeder Fehlermeldung und dem Objekt aufgerufen wird. Dieses Beispiel stammt 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. Es gibt auch ein Beispiel in der AWS-Dokumentation:
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);
quelle
new Promise((resolve, reject) => {s3.getObject(params).createReadStream().on('end', () => { return resolve(); }).on('error', (error) => { return reject(error); }).pipe(file)});
if (typeof Promise === 'undefined') { console.log("Using Bluebird for Promises"); AWS.config.setPromisesDependency(require('bluebird')); }
Dies wird es tun:
new AWS.S3().getObject({ Bucket: this.awsBucketName, Key: keyName }, function(err, data) { if (!err) console.log(data.Body.toString()); });
quelle
Da Sie scheinbar eine S3-Textdatei Zeile für Zeile verarbeiten möchten. Hier ist eine Knotenversion, die das Standard-Readline-Modul und AWS 'createReadStream () 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() { });
quelle
end
Veranstaltung heißtclose
stattdessen. nodejs.org/api/readline.html#readline_event_closes3.getObject(params).createReadStream().pipe(zlib.createGunzip())
als InputStream verwenden ...Hier ist das Beispiel, mit dem ich JSON-Daten von S3 abgerufen und analysiert habe.
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 ...... } });
quelle
Ich konnte noch nicht herausfinden warum, aber der
createReadStream
/pipe
-Ansatz hat bei mir nicht funktioniert. Ich habe versucht, eine große CSV-Datei (über 300 MB) herunterzuladen, und habe doppelte Zeilen erhalten. Es schien ein zufälliges Problem zu sein. Die endgültige Dateigröße variierte bei jedem Versuch, sie herunterzuladen.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.
quelle
Wenn Sie Speicherplatz sparen und jede Zeile als JSON-Objekt erhalten möchten, können Sie
fast-csv
Readstream erstellen und jede Zeile wie folgt als JSON-Objekt 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'); });
quelle
Ich bevorzuge
Buffer.from(data.Body).toString('utf8')
. Es unterstützt Codierungsparameter. Bei anderen AWS-Diensten (z. B. Kinesis Streams) möchte möglicherweise jemand die'utf8'
Codierung durch ersetzen'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); } } );
quelle
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);
Während diese Lösung funktioniert:
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 abfeuert einfach nicht dasend
,close
odererror
aus irgendeinem Grund des Rückrufs. Siehe hier dazu.Ich verwende diese Lösung auch zum Aufschreiben von Archiven in gzip, da das erste (AWS-Beispiel) auch in diesem Fall 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();
quelle
Mit der neuen Version von sdk funktioniert die akzeptierte Antwort nicht - sie wartet nicht darauf, dass das Objekt heruntergeladen wird. Das folgende Code-Snippet hilft bei der neuen Version:
// dependencies const AWS = require('aws-sdk'); // get reference to S3 client const s3 = new AWS.S3(); exports.handler = async (event, context, callback) => { var bucket = "TestBucket" var key = "TestKey" try { const params = { Bucket: Bucket, Key: Key }; var theObject = await s3.getObject(params).promise(); } catch (error) { console.log(error); return; } }
quelle
Wenn Sie die Rückrufe vermeiden möchten, können Sie die Funktion sdk .promise () wie folgt nutzen:
const s3 = new AWS.S3(); const params = {Bucket: 'myBucket', Key: 'myKey.csv'} const response = await s3.getObject(params).promise() // await the promise const fileContent = getObjectResult.Body.toString('utf-8'); // can also do 'base64' here if desired
Ich bin sicher, dass die anderen hier genannten Möglichkeiten ihre Vorteile haben, aber das funktioniert großartig für mich. Aus diesem Thread bezogen (siehe die letzte Antwort von AWS): https://forums.aws.amazon.com/thread.jspa?threadID=116788
quelle
var fileStream = fs.createWriteStream('/path/to/file.jpg'); var s3Stream = s3.getObject({Bucket: 'myBucket', Key: 'myImageFile.jpg'}).createReadStream(); // Listen for errors returned by the service s3Stream.on('error', function(err) { // NoSuchKey: The specified key does not exist console.error(err); }); s3Stream.pipe(fileStream).on('error', function(err) { // capture any errors that occur when writing data to the file console.error('File Stream:', err); }).on('close', function() { console.log('Done.'); });
Referenz: https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/requests-using-stream-objects.html
quelle