节点 AWS S3 getObject 在文件流完成之前触发 httpDone
Node AWS S3 getObject firing httpDone before file stream completes
我在节点应用程序中使用 AWS s3 getObject 方法下载一个 zip 文件,然后使用 child_process.exec 对其调用解压缩:
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 节点库中是否存在错误,或者我使用了错误的完成事件?
您应该改为在文件流的 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');
});
我在节点应用程序中使用 AWS s3 getObject 方法下载一个 zip 文件,然后使用 child_process.exec 对其调用解压缩:
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 节点库中是否存在错误,或者我使用了错误的完成事件?
您应该改为在文件流的 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');
});