2015-11-24 87 views
2

我使用AWS S3 getObject方法中的一個節點應用程序下載一個壓縮文件,然後使用child_process.exec調用解壓縮就可以了:節點AWS S3的getObject文件流之前發射httpDone完成

var file = fs.createWriteStream(file_path); 
s3.getObject(params). 
on('httpData', function(chunk) { 
    process.stdout.write("."); 
    file.write(chunk); 
}). 
on('httpDone', function() { 
    file.end(); 
    console.log('Download Complete'); 
    self.emit('downloadComplete'); 
}). 
send(); 

,並在downloadComplete事件,該代碼被調用,它引發錯誤:

exec = require('child_process').exec; 
exec('unzip -o -qq ' + src + ' -d ' + dest, function (error, stdout, stderr) { 
    callback(stderr); 
}); 

的exec調用回來與此錯誤:

End-of-central-directory signature not found. Either this file is not 
a zipfile, or it constitutes one disk of a multi-part archive. In the 
latter case the central directory and zipfile comment will be found on 
the last disk(s) of this archive. 

但是,如果我設置了短超時之前,我嘗試解壓縮,即:

setTimeout(function() { 
    self.emit('downloadComplete'); 
}, 100); 

它的工作原理。 AWS節點庫中是否存在錯誤,或者可能使用了錯誤的完成事件?

回答

5

而應該發出您下載完整的事件在文件流finish事件處理程序:

var file = fs.createWriteStream(file_path); 
file.on('finish', function() { 
    self.emit('downloadComplete'); 
}); 
s3.getObject(params). 
    on('httpData', function(chunk) { 
    process.stdout.write("."); 
    file.write(chunk); 
    }). 
    on('httpDone', function() { 
    file.end(); 
    console.log('Download Complete'); 
    }). 
    send(); 

在一個不相關的音符,你應該也可以使用一般數據流,使背壓可以當做它的事磁盤跟不上。例如:

var file = fs.createWriteStream(file_path); 
s3.getObject(params) 
    .createReadStream() 
    .pipe(file) 
    .on('finish', function() { 
    self.emit('downloadComplete'); 
    }); 
+0

可笑地快速回答,解決了問題並改進了我的代碼。非常感謝。非關鍵:在第二個代碼片段中,httpData事件似乎不再被解僱 - 還有什麼方法可以在大型下載期間提供反饋?乾杯 – wildabeast

+1

'httpData'不會觸發,因爲它是一個普通的流('createReadStream()')。你可以監聽流到'file'的數據流上的'data'和'end'事件來知道數據何時通過。 – mscdex

相關問題