我正在入侵一个Node程序,该程序使用SMTP协议捕获SMTP电子邮件并对邮件数据采取行动。库将邮件数据作为流提供,但我不知道如何将其转换为字符串。

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

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


当前回答

你觉得这个怎么样?

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

其他回答

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

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

流没有简单的. tostring()函数(我理解),也没有类似于. tostringasync (cb)函数(我不理解)的东西。

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

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

你觉得这个怎么样?

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

所有列出的答案似乎都以流动模式打开可读流,这不是NodeJS的默认模式,并且可能有局限性,因为它缺乏NodeJS在暂停可读流模式中提供的反压力支持。 这里是一个使用Just Buffers、本机流和本机流转换并支持对象模式的实现

import {Transform} from 'stream';

let buffer =null;    

function objectifyStream() {
    return new Transform({
        objectMode: true,
        transform: function(chunk, encoding, next) {

            if (!buffer) {
                buffer = Buffer.from([...chunk]);
            } else {
                buffer = Buffer.from([...buffer, ...chunk]);
            }
            next(null, buffer);
        }
    });
}

process.stdin.pipe(objectifyStream()).process.stdout

另一种方法是将流转换为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)