如何将来自Node.js流的所有数据收集到字符串中?
如何将来自Node.js流的所有数据收集到字符串中?
另一种方法是将流转换为一个promise(请参考下面的示例),并使用then
(或await
)将已解决的值分配给变量。
function streamToString (stream) {
const chunks = [];
return new Promise((resolve, reject) => {
stream.on('data', (chunk) => chunks.push(Buffer.from(chunk)));
stream.on('error', (err) => reject(err));
stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
})
}
const result = await streamToString(stream)
streamToString(stream).then(function(response){//对response进行任何操作});
- Enclo CreationsBuffers
,并仅在最后调用 .toString("utf8")
,避免了当块在多字节字符中间分割时可能出现的解码错误问题;实现了真正的错误处理;将代码放在一个函数中,以便重复使用,而不是复制粘贴;使用 Promises,因此可以等待函数执行完毕;代码量小,不像某些 npm 库那样拖累了数百个依赖项;使用了 ES6 语法和现代最佳实践。 - MultiplyByZer0chunks.push(Buffer.from(chunk))
应该适用于“string”和“Buffer”块。 - Andrei LED你对此有何看法?
async function streamToString(stream) {
// lets have a ReadableStream as a stream variable
const chunks = [];
for await (const chunk of stream) {
chunks.push(Buffer.from(chunk));
}
return Buffer.concat(chunks).toString("utf-8");
}
chunks.push(Buffer.from(chunk));
来处理字符串块以使其正常工作。 - Janfor await
是有效的ECMAScript语法),或者如果它尝试(不成功地)执行包含for await
的代码,则IDE本身已经过时。这是哪个IDE?无论如何,IDE并不是为了实际在生产中运行程序而设计的,它们会在开发期间对程序进行lint和分析。 - Armen Michaeli以上方法均不适用于我。我需要使用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));
});
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文本产生不可预测的故障(它假设每个字符都适合一个字节),但也许您也不关心这一点。
join("")
。 - Valeriu PaloştoString('utf8')
- 但默认的字符串编码是 utf8
,所以我怀疑你的流可能不是 utf8
@alextgordon - 参见 https://dev59.com/hGct5IYBdhLWcg3wZcmL 获取更多信息。 - Tom Carchrae我通常使用这个简单函数将流转换为字符串:
function streamToString(stream, cb) {
const chunks = [];
stream.on('data', (chunk) => {
chunks.push(chunk.toString());
});
stream.on('end', () => {
cb(chunks.join(''));
});
}
使用示例:
let stream = fs.createReadStream('./myFile.foo');
streamToString(stream, (data) => {
console.log(data); // data is now my string variable
});
chunks.push(chunk.toString());
- Nicolas Le Thierry d'Ennequin还有一个使用 promises 处理字符串的示例:
function getStream(stream) {
return new Promise(resolve => {
const chunks = [];
# Buffer.from is required if chunk is a String, see comments
stream.on("data", chunk => chunks.push(Buffer.from(chunk)));
stream.on("end", () => resolve(Buffer.concat(chunks).toString()));
});
}
使用方法:
const stream = fs.createReadStream(__filename);
getStream(stream).then(r=>console.log(r));
如有需要,删除.toString()
以与二进制数据一起使用。
更新:@AndreiLED正确指出这对字符串存在问题。我无法在我使用的node版本中获得返回字符串的流,但api注意到这是可能的。
Uncaught TypeError [ERR_INVALID_ARG_TYPE]: The "list[0]" argument must be an instance of Buffer or Uint8Array. Received type string
,如果流产生的是 string
块而不是 Buffer
。使用 chunks.push(Buffer.from(chunk))
可以处理 string
和 Buffer
块。 - Andrei LED使用流行的(每周下载量超过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 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);
})
我曾经用过以下方法:
let string = '';
readstream
.on('data', (buf) => string += buf.toString())
.on('end', () => console.log(string));
我使用的是 Node v9.11.1
版本,readstream
是从一个 http.get
回调函数中返回的响应。