简体   繁体   English

在 Node.js 数据流中通过换行获取块

[英]Getting chunks by newline in Node.js data stream

At one point I thought you could tell Node.js child process to chunk the data by newline character.一度我认为你可以告诉 Node.js 子进程按换行符分块数据。 As is below, the stderr data event from the child process is firing for characters and words, not lines.如下所示,来自子进程的 stderr 数据事件触发的是字符和单词,而不是行。 Ideally I could pass a flag to tell the stream to only fire the data event when a line of data is ready.理想情况下,我可以传递一个标志来告诉流仅在一行数据准备好时才触发数据事件。 Isn't there a way to do this?没有办法做到这一点吗?

I have this:我有这个:

const sh = spawn('sh', [ b ], {
  cwd: cwd,
});

sh.stdout.pipe(fs.createWriteStream('/dev/null'));

var stderr = '';
var line = '';

sh.stderr.setEncoding('utf8');

sh.stderr.on('data', function (d) {

  //trying to split by newlines, but this is hairy logic
  const lines = String(d).split('\n');

  line += lines.shift();

  if(lines.length > 0){

    if (!String(d).match(/npm/ig) && !String(d).match(/npm/ig)) {
      stderr += d;
      process.stderr.write.apply(process.stderr, arguments);
    }

  }

});

and the data come back in this handler is not whole lines并且在此处理程序中返回的数据不是整行

sh.stderr.on('data', function (d) {
   // d is chunks of data but not whole lines
});

isn't there a way to tell stderr to wait for newline chars before firing the 'data' event?有没有办法告诉 stderr 在触发“数据”事件之前等待换行符?

You can use a Transform stream for that.您可以为此使用转换流

The implementation is not so trivial, so I would recommend using a library like split2 .实现并不是那么简单,所以我建议使用像split2这样的库。

Here is the basic idea :这是基本思想:

const Transform = require('stream').Transform;
const StringDecoder = require('string_decoder').StringDecoder;

const decoder = new StringDecoder('utf8');

const myTransform = new Transform({
   transform(chunk, encoding, cb) {
      if ( this._last === undefined ) { this._last = "" }
      this._last += decoder.write(chunk);
      var list = this._last.split(/\n/);          
      this._last = list.pop();
      for (var i = 0; i < list.length; i++) {
        this.push( list[i] );
      }
      cb();
  },

  flush(cb) {
      this._last += decoder.end()
      if (this._last) { this.push(this._last) }
      cb()
  }
});

sh.stderr.pipe( myTransform )
         .on('data', function (line) {
              console.log("[" + line + "]");
         });    

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM