Search code examples
node.jsstreampipeclone

Node.js copy a stream into a file without consuming


Given a function parses incoming streams:

async onData(stream, callback) {
    const parsed = await simpleParser(stream)

    // Code handling parsed stream here
    // ...

    return callback()
}

I'm looking for a simple and safe way to 'clone' that stream, so I can save it to a file for debugging purposes, without affecting the code. Is this possible?

Same question in fake code: I'm trying to do something like this. Obviously, this is a made up example and doesn't work.

const fs = require('fs')
const wstream = fs.createWriteStream('debug.log')

async onData(stream, callback) {
    const debugStream = stream.clone(stream) // Fake code
    wstream.write(debugStream)

    const parsed = await simpleParser(stream)

    // Code handling parsed stream here
    // ...

    wstream.end()

    return callback()
}

Solution

  • No you can't clone a readable stream without consuming. However, you can pipe it twice, one for creating file and the other for 'clone'.

    Code is below:

    let Readable = require('stream').Readable;
    var stream = require('stream')
    
    // original stream, maybe from your parser or network
    var s = new Readable()
    s.push('beep')
    s.push(null)  
    
    // here use stream1 for normal usage, like creating file, 
    // and use stream2 for debugging, like a cloned stream.
    var stream1 = s.pipe(new stream.PassThrough())
    var stream2 = s.pipe(new stream.PassThrough())
    
    // I just print them out for a quick show
    stream1.pipe(process.stdout)
    stream2.pipe(process.stdout)