【问题标题】:Transform stream, accessing internal data转换流,访问内部数据
【发布时间】:2016-07-07 08:08:27
【问题描述】:

我想读取一个文件(理想情况下使用fs.createReadStream,通过转换过程将其通过管道传输,然后将其写入(理想情况下使用fs.createWriteStream)到另一个文件。

我为此使用了转换流 (new stream.Transform()),它似乎可以工作,但现在我被卡住了

在我有的转换流的flush方法中

 strm._flush = function (done) {
        if (this._lastLineData) {
            this.push(this._lastLineData + '\n');
        }
        this._lastLineData = null;
        done();
    };

我希望能够修改转换存储数据的内部数据结构中的一些数据。如何访问该内部数据结构。

换句话说,this.push 肯定会推入某个数组,我希望能够在 _flush 方法中读取该数组的某些元素。

进入节点核心,我看到了:

Transform.prototype.push = function(chunk, encoding) {
  this._transformState.needTransform = false;
  return Duplex.prototype.push.call(this, chunk, encoding);
};

Readable.prototype.push = function(chunk, encoding) {
  var state = this._readableState;

  if (!state.objectMode && typeof chunk === 'string') {
    encoding = encoding || state.defaultEncoding;
    if (encoding !== state.encoding) {
      chunk = new Buffer(chunk, encoding);
      encoding = '';
    }
  }

  return readableAddChunk(this, state, chunk, encoding, false);
};

function readableAddChunk(stream, state, chunk, encoding, addToFront) {
  var er = chunkInvalid(state, chunk);
  if (er) {
    stream.emit('error', er);
  } else if (chunk === null) {
    state.reading = false;
    onEofChunk(stream, state);
  } else if (state.objectMode || chunk && chunk.length > 0) {
    if (state.ended && !addToFront) {
      var e = new Error('stream.push() after EOF');
      stream.emit('error', e);
    } else if (state.endEmitted && addToFront) {
      var e = new Error('stream.unshift() after end event');
      stream.emit('error', e);
    } else {
      if (state.decoder && !addToFront && !encoding)
        chunk = state.decoder.write(chunk);

      if (!addToFront)
        state.reading = false;

      // if we want the data now, just emit it.
      if (state.flowing && state.length === 0 && !state.sync) {
        stream.emit('data', chunk);
        stream.read(0);
      } else {
        // update the buffer info.
        state.length += state.objectMode ? 1 : chunk.length;
        if (addToFront)
          state.buffer.unshift(chunk);
        else
          state.buffer.push(chunk);

        if (state.needReadable)
          emitReadable(stream);
      }

      maybeReadMore(stream, state);
    }
  } else if (!addToFront) {
    state.reading = false;
  }

  return needMoreData(state);
}

所以在我看来没有简单的方法来获取内部数据?

【问题讨论】:

    标签: node.js node.js-stream


    【解决方案1】:

    你不能这样做。

    应该使用流来管道数据从一个地方到另一个地方。如果您想修改整个数据(在将其通过管道传输到下一个流之前),那么您根本不应该使用流。将它们视为无尽的数据流

    你可以做的是:

    var data = [];
    
    stream._transform = function(chunk, enc, done) { 
       data.push(chunk);
       done(chunk);
    }
    
    stream._flush = function(done) { 
       /** ... Do something with data ... */
       data = []; // Null data variable, to allow GC collecting it.
       done();
    };
    

    【讨论】:

      猜你喜欢
      • 2021-08-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-16
      • 1970-01-01
      • 2021-09-14
      • 2019-05-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多