2016-03-20 5 views
0

Я хочу, чтобы прочитать файл (в идеале с fs.createReadStream, трубами через процесс преобразования, а затем записать его (в идеале с помощью fs.createWriteStream) в другой файл.преобразование потока, доступ к внутренним данным

Я использую преобразование потока (new stream.Transform()) для этого, и это, кажется, работает, за исключением того, теперь я застрял

в смывной способе преобразования потока у меня есть

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

Я хочу, чтобы иметь возможность изменить некоторые данные во внутренних данных s где трансформация хранит данные. Как я могу получить доступ к этой внутренней структуре данных.

Другими словами, 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); 
} 

так мне кажется, нет простого способа получить на внутренние данные?

ответ

0

Вы не можете этого сделать.

Какие потоки следует использовать для труба данные из одного места в другое. Если вы хотите изменить все данные (прежде чем перевести их в следующий поток), вы не должны использовать поток вообще. Думайте о них как бесконечный поток данных.

Что вы можете сделать, это:

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(); 
}; 
Смежные вопросы