2014-12-04 52 views
39

我試圖讀取使用讀取AWS S3存儲使用節點文件FS

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

我已經能夠下載和使用節點aws-上傳文件的文件是在AWS S3存儲桶sdk,但我對如何簡單閱讀並解析內容感到茫然。

下面是我如何從S3讀取該文件的例子:

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

contents.Body.toString(),而不是內容.Body – Jason 2016-04-20 00:00:37

回答

53

你有幾個選項。您可以包含一個回調作爲第二個參數,該參數將被任何錯誤消息和對象調用。這example是直接從AWS文檔:

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

或者,您可以將輸出轉換成流。另外還有AWS文檔中的example

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

如果我還希望使用Promise來更好地進行整體異步處理,該怎麼辦? – verveguy 2016-08-24 03:17:37

+7

@verveguy您可以使用以下內容:'new Promise((resolve,reject)=> {s3.getObject(params).createReadStream()。on('end',()=> {return resolve();}) .on('error',(error)=> {return reject(error);})。pipe(file)});' – 2016-09-29 13:37:29

+1

@verveguy根據您運行的節點版本,aws-sdk版本> 2.3 .0,將使用原生承諾。您還可以明確配置您想要使用的承諾庫。 'if(typeof Promise ==='undefined'){ console.log(「使用Bluebird作爲承諾」); AWS.config.setPromisesDependency(require('bluebird')); }' – alexhb 2016-11-23 19:29:44

24

這將做到這一點:

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

使用console.log而不是警報nodejs – dpineda 2015-06-23 20:35:11

+3

這不是關鍵人物,重要的是,OP所需要的是存儲在data.Body中,而不僅僅是在數據中(正如其他答案所建議的那樣)。我敢肯定,OP將取代任何他需要的警報。 – 2015-06-25 07:23:57

+0

是的,但如果你不測試你的sniped代碼嘗試elavorete描述 – dpineda 2015-06-25 15:46:01

14

因爲你似乎要處理的S3文本文件行由行。下面是使用標準的readline模塊和AWS」 createReadStream()

const readline = require('readline'); 

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

rl.on('line', function(line) { 
    console.log(line); 
}) 
.on('close', function() { 
}); 
+1

一個美妙的記憶保護程序。謝謝! – 2016-07-05 20:10:55

+1

我認爲'end'事件被稱爲'close'。 https://nodejs.org/api/readline.html#readline_event_close – 2017-01-13 20:56:33

+1

如果你想處理gzip源文件,你可以使用s3.getObject(params).createReadStream()。pipe(zlib.createGunzip())'as InputStream以及... – Tobi 2018-01-17 20:55:55

3

這裏是我用以檢索和從S3解析JSON數據的例子的節點版本。

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

這會減慢我的代碼,當json_data是一個大的json數組... – 2016-12-02 05:41:35

5

我想不出爲什麼呢,但createReadStream/pipe做法並沒有爲我工作。我試圖下載一個大的CSV文件(300MB +),我得到了重複的行。這似乎是一個隨機問題。每次嘗試下載最終文件大小都會有所不同。

最後我用另一種方式的基礎上,AWS JS SDK examples

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

這樣一來,它的工作就像一個魅力。

2

從S3非常大的文件下載時,我有完全相同的問題。

從AWS文檔中的示例解決方案是行不通的:

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

雖然這種解決方案將工作:

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

createReadStream嘗試只是不火的endcloseerror回調一些原因。關於這個請看here

我使用的解決方案也爲檔案寫下來gzip的,因爲第一個(AWS實例)不會在這種情況下工作,要麼:

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