我需要通过http请求触发一个过程,在该过程中,我从S3下载一些数据,对数据进行压缩,修改流,对它进行gzip,然后发送到S3中的另一个存储桶。
到目前为止,我能够:
或者:
我的第一个尝试包括使用gunzip流中的 on('data')事件来修改数据;然后当引发“结束”事件时,我可以将其返回给发出请求的浏览器。
var accumulator = [];
gunzip.on('data', chunk=>{
var lines = chunk.toString('utf-8').split(\n);
lines.forEach(line=>{
if(shouldBeFiltered(line)){
accumulator.push(line);
}
})
})
gunzip.on('end', ()=>{
res.send(accumulator);
})
getS3.pipe(gunzip)
如果我不返回结果(res.send),而是尝试将gunzip传递给gzip,则忽略过滤器。之所以有意义,是因为我有一个 accumulator 数组,在引发结束事件时我返回了(在前面的情况下)。
然后,在进行一些挖掘之后,我发现了一个参考文献,建议应将数据推入,然后尝试了以下操作,但这是行不通的:
gunzip.on('data', chunk=>{
var lines = chunk.toString('utf-8').split(\n);
lines.forEach(line=>{
if(shouldBeFiltered(line)){
gunzip.push(line);
}
})
})
// the end event no longer mattered
// gunzip.on('end', ()=>{
// res.send(accumulator);
// })
getS3.pipe(gunzip).pipe(gzip).pipe(putS3(putS3param.Key, putS3param.Bucket));
然后我尝试创建一个转换流(在尝试该概念时,这非常简化),但是随后出现内部错误:
const stream = require('stream');
const Transform = stream.Transform;
function filter(pipeline) {
var the_filter = new Transform({
transform(chunk, encoding, next) {
console.log();
chunk += Buffer('Modified', 'utf-8');
this.push(chunk);
next();
}
});
pipeline.pipe(the_filter);
}
除了创建文件并将其gzip压缩并上传外,我没有其他想法。
感谢您的帮助!
答案 0 :(得分:0)
深入研究之后,我终于在此page
中找到了答案似乎没有将Transform设置为 objectMode 的东西,除此之外,我看不到任何相关信息。
var stream = require('stream')
var liner = new stream.Transform( { objectMode: true } )
liner._transform = function (chunk, encoding, done) {
var data = chunk.toString()
if (this._lastLineData) data = this._lastLineData + data
var lines = data.split('\n')
this._lastLineData = lines.splice(lines.length-1,1)[0]
lines.forEach(this.push.bind(this))
done()
}
liner._flush = function (done) {
if (this._lastLineData) this.push(this._lastLineData)
this._lastLineData = null
done()
}
module.exports = liner