2017-03-07 58 views
1

這使我變得瘋狂。無法使用nodeJS從S3下載文件:很少有文件沒有完成

我需要我的服務器從S3(最大2 Mb)下載100個相對較小的文件文件。

它總是對大約95%的文件起作用,但會阻塞最後的6-8個文件。該resolve也不reject回調得到從來沒有所謂的...

我試圖下載並行文件...

  • 任何人都經歷過這樣的?
  • 難道是一個數據包丟失,流不關閉?
  • 是否有最大數量的併發下載?

下面的代碼,這在技術上工程的情況下,95%:

let singleGetFromS3 = (bucket, fileName) => { 
    return new Promise((resolve, reject) => { 
     let extension = getFileNameExtension(fileName); 
     fs.stat(`./${fileName}`, (err, stat) => { 
     if (err === null) { 
      console.log(`${fileName} exists locally`); 
      resolve(fileName); 
     } else if(err.code === 'ENOENT') { 
      let params = {Bucket: bucket, Key: fileName}; 
      let file = require('fs').createWriteStream(`./tmp-${fileName}`); 
      s3.getObject(params).createReadStream() 
      .on('error', (error) => { return reject(error); }) 
      .on('end',() => { 
       fs.rename(`./tmp-${fileName}`, `./${fileName}`, reject); 
       return resolve(fileName); 
      }) 
      .pipe(file); 
     } else { 
      reject(err); 
     } 
     }); 
    }); 
    }; 

使用:

"aws-sdk": "^2.23.0", 
node --version 
v4.5.0 

回答

2

看起來你正在聽的關於何時解決錯誤的事件。當您從S3的Readable中讀取所有字節時,您不想解析所有字節,當您想要在file完成寫入時解析。

let singleGetFromS3 = (bucket, fileName) => { 
    return new Promise((resolve, reject) => { 
     let extension = getFileNameExtension(fileName); 
     fs.stat(`./${fileName}`, (err, stat) => { 
     if (err === null) { 
      console.log(`${fileName} exists locally`); 
      resolve(fileName); 
     } else if(err.code === 'ENOENT') { 
      let params = {Bucket: bucket, Key: fileName}; 
      let file = require('fs').createWriteStream(`./tmp-${fileName}`);  

      // Listen for the file to be done writing, then resolve 
      file.on('finish',() => { 
       fs.rename(`./tmp-${fileName}`, `./${fileName}`, reject); 
       return resolve(fileName); 
      }) 

      s3.getObject(params).createReadStream() 
      .on('error', (error) => { return reject(error); }) 
      .pipe(file); 
     } else { 
      reject(err); 
     } 
     }); 
    }); 
    }; 
+0

謝謝。我想過這個,但沒有想到writeStream關閉自己的原因。但顯然它的工作原理,但我仍然有5〜6個文件沒有完成...... :(:( –

+0

順便說一句,我很驚訝地發現S3中的這種微不足道的操作在nodeJS中是如此痛苦... –

+0

@AugustinRiedinger如果你想簡化這一點,我會開始不使用回調,事件/流和承諾所有在同一個函數。你應該使用bluebird.js'promisify'你的'FS',所以你不要需要'fs.stat()'回調,並且我編輯了答案,不要使用我最初提出的'close'事件,而是使用'finish'代替 – peteb