我正在入侵一个Node程序,该程序使用SMTP协议捕获SMTP电子邮件并对邮件数据采取行动。库将邮件数据作为流提供,但我不知道如何将其转换为字符串。
我目前正在用stream.pipe(process. pipe)将其写入标准输出。stdout, {end: false}),但正如我所说的,我需要一个字符串中的流数据,一旦流结束,我就可以使用它。
我如何收集所有的数据从一个Node.js流到一个字符串?
我正在入侵一个Node程序,该程序使用SMTP协议捕获SMTP电子邮件并对邮件数据采取行动。库将邮件数据作为流提供,但我不知道如何将其转换为字符串。
我目前正在用stream.pipe(process. pipe)将其写入标准输出。stdout, {end: false}),但正如我所说的,我需要一个字符串中的流数据,一旦流结束,我就可以使用它。
我如何收集所有的数据从一个Node.js流到一个字符串?
当前回答
最简洁的解决方案可能是使用“string-stream”包,它将流转换为带有承诺的字符串。
const streamString = require('stream-string')
streamString(myStream).then(string_variable => {
// myStream was converted to a string, and that string is stored in string_variable
console.log(string_variable)
}).catch(err => {
// myStream emitted an error event (err), so the promise from stream-string was rejected
throw err
})
其他回答
简单易用的流行(每周超过500万次下载)和轻量级的get-stream库:
https://www.npmjs.com/package/get-stream
const fs = require('fs');
const getStream = require('get-stream');
(async () => {
const stream = fs.createReadStream('unicorn.txt');
console.log(await getStream(stream)); //output is string
})();
希望这比上面的答案更有用:
var string = '';
stream.on('data',function(data){
string += data.toString();
console.log('stream data ' + part);
});
stream.on('end',function(){
console.log('final output ' + string);
});
请注意,字符串连接并不是收集字符串部分的最有效方法,但使用它是为了简单(也许您的代码并不关心效率)。
此外,对于非ascii文本,这段代码可能会产生不可预测的失败(它假设每个字符都适合一个字节),但也许您也不关心这一点。
以上这些方法对我都没用。我需要使用Buffer对象:
const chunks = [];
readStream.on("data", function (chunk) {
chunks.push(chunk);
});
// Send the buffer or you can put it into a var
readStream.on("end", function () {
res.send(Buffer.concat(chunks));
});
从nodejs文档中,你应该这样做——永远记住一个字符串,而不知道编码只是一堆字节:
var readable = getReadableStreamSomehow();
readable.setEncoding('utf8');
readable.on('data', function(chunk) {
assert.equal(typeof chunk, 'string');
console.log('got %d characters of string data', chunk.length);
})
像减流器这样的东西怎么样?
下面是一个使用ES6类的例子如何使用一个。
var stream = require('stream')
class StreamReducer extends stream.Writable {
constructor(chunkReducer, initialvalue, cb) {
super();
this.reducer = chunkReducer;
this.accumulator = initialvalue;
this.cb = cb;
}
_write(chunk, enc, next) {
this.accumulator = this.reducer(this.accumulator, chunk);
next();
}
end() {
this.cb(null, this.accumulator)
}
}
// just a test stream
class EmitterStream extends stream.Readable {
constructor(chunks) {
super();
this.chunks = chunks;
}
_read() {
this.chunks.forEach(function (chunk) {
this.push(chunk);
}.bind(this));
this.push(null);
}
}
// just transform the strings into buffer as we would get from fs stream or http request stream
(new EmitterStream(
["hello ", "world !"]
.map(function(str) {
return Buffer.from(str, 'utf8');
})
)).pipe(new StreamReducer(
function (acc, v) {
acc.push(v);
return acc;
},
[],
function(err, chunks) {
console.log(Buffer.concat(chunks).toString('utf8'));
})
);