Javascript 如何将 Node.js 流的内容读入字符串变量?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10623798/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 02:12:18  来源:igfitidea点击:

How do I read the contents of a Node.js stream into a string variable?

javascriptnode.jsstream

提问by obrienmd

I'm hacking on a Node program that uses smtp-protocolto capture SMTP emails and act on the mail data. The library provides the mail data as a stream, and I don't know how to get that into a string.

我正在破解一个smtp-protocol用于捕获 SMTP 电子邮件并处理邮件数据的 Node 程序。该库将邮件数据作为流提供,我不知道如何将其转换为字符串。

I'm currently writing it to stdout with stream.pipe(process.stdout, { end: false }), but as I said, I need the stream data in a string instead, which I can use once the stream has ended.

我目前正在使用 将其写入标准输出stream.pipe(process.stdout, { end: false }),但正如我所说,我需要字符串中的流数据,一旦流结束,我就可以使用它。

How do I collect all the data from a Node.js stream into a string?

如何将 Node.js 流中的所有数据收集到一个字符串中?

采纳答案by ControlAltDel

The key is to use the dataand endevents of a Readable Stream. Listen to these events:

关键是使用Readable Streamdataend事件。收听这些事件:

stream.on('data', (chunk) => { ... });
stream.on('end', () => { ... });

When you receive the dataevent, add the new chunk of data to a Buffer created to collect the data.

当您收到data事件时,将新的数据块添加到为收集数据而创建的缓冲区中。

When you receive the endevent, convert the completed Buffer into a string, if necessary. Then do what you need to do with it.

收到end事件后,如有必要,将完成的 Buffer 转换为字符串。然后做你需要做的事情。

回答by Marlon Bernardes

Another way would be to convert the stream to a promise (refer to the example below) and use then(or await) to assign the resolved value to a variable.

另一种方法是将流转换为承诺(请参阅下面的示例)并使用then(or await) 将解析的值分配给变量。

function streamToString (stream) {
  const chunks = []
  return new Promise((resolve, reject) => {
    stream.on('data', chunk => chunks.push(chunk))
    stream.on('error', reject)
    stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')))
  })
}

const result = await streamToString(stream)

回答by Tom Carchrae

Hope this is more useful than the above answer:

希望这比上面的答案更有用:

var string = '';
stream.on('data',function(data){
  string += data.toString();
  console.log('stream data ' + part);
});

stream.on('end',function(){
  console.log('final output ' + string);
});

Note that string concatenation is not the most efficient way to collect the string parts, but it is used for simplicity (and perhaps your code does not care about efficiency).

请注意,字符串连接并不是收集字符串部分的最有效方法,但它只是为了简单起见(也许您的代码并不关心效率)。

Also, this code may produce unpredictable failures for non-ASCII text (it assumes that every character fits in a byte), but perhaps you do not care about that, either.

此外,此代码可能会为非 ASCII 文本产生不可预测的失败(它假定每个字符都适合一个字节),但也许您也不关心这一点。

回答by Ricky

None of the above worked for me. I needed to use the Buffer object:

以上都不适合我。我需要使用 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));
  });

回答by dreampulse

I'm using usually this simple function to transform a stream into a string:

我通常使用这个简单的函数将流转换为字符串:

function streamToString(stream, cb) {
  const chunks = [];
  stream.on('data', (chunk) => {
    chunks.push(chunk.toString());
  });
  stream.on('end', () => {
    cb(chunks.join(''));
  });
}

Usage example:

用法示例:

let stream = fs.createReadStream('./myFile.foo');
streamToString(stream, (data) => {
  console.log(data);  // data is now my string variable
});

回答by Sebastian J.

From the nodejs documentationyou should do this - always remember a string without knowing the encoding is just a bunch of bytes:

从 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);
})

回答by estani

And yet another one for strings using promises:

还有另一个使用 Promise 的字符串:

function getStream(stream) {
  return new Promise(resolve => {
    const chunks = [];

    stream.on("data", chunk => chunks.push(chunk));
    stream.on("end", () => resolve(Buffer.concat(chunks).toString()));
  });
}

Usage:

用法:

const stream = fs.createReadStream(__filename);
getStream(stream).then(r=>console.log(r));

remove the .toString()to use with binary Data if required.

.toString()如果需要,删除与二进制数据一起使用的 。

回答by flori

Streams don't have a simple .toString()function (which I understand) nor something like a .toStringAsync(cb)function (which I don't understand).

Streams 没有简单的.toString()函数(我理解),也没有类似.toStringAsync(cb)函数的东西(我不理解)。

So I created my own helper function:

所以我创建了自己的辅助函数:

var streamToString = function(stream, callback) {
  var str = '';
  stream.on('data', function(chunk) {
    str += chunk;
  });
  stream.on('end', function() {
    callback(str);
  });
}

// how to use:
streamToString(myStream, function(myStr) {
  console.log(myStr);
});

回答by vdegenne

I had more luck using like that :

我有更多的运气使用这样的:

let string = '';
readstream
    .on('data', (buf) => string += buf.toString())
    .on('end', () => console.log(string));

I use node v9.11.1and the readstreamis the response from a http.getcallback.

我使用节点v9.11.1,这readstream是来自http.get回调的响应。

回答by Ville

Easy way with the popular (over 5m weekly downloads) and lightweight get-streamlibrary:

使用流行的(每周下载量超过 500 万次)和轻量级的get-stream库的简单方法:

https://www.npmjs.com/package/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
})();