2015-11-24 51 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

相关问题