Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reset nodejs stream?

Tags:

stream

node.js

fs

How to reset nodejs stream? How to read stream again in nodejs? Thanks in advance!

var fs = require('fs');
var lineReader = require('line-reader');

// proxy.txt = only 3 lines

var readStream = fs.createReadStream('proxy.txt');
lineReader.open(readStream, function (err, reader) {
    for(var i=0; i<6; i++) {
        reader.nextLine(function(err, line) {
            if(err) {
                readStream.reset(); // ???
            } else {
                console.log(line);
            }
        });
    }
});
like image 220
Игорь Avatar asked May 02 '16 10:05

Игорь


1 Answers

There are two ways of solving your problem, as someone commented before you could simply wrap all that in a function and instead of resetting - simply read the file again.

Ofc this won't work well with HTTP requests for example so the other way, provided that you do take a much bigger memory usage into account, you can simply accumulate your data.

What you'd need is to implement some sort of "rewindable stream" - this means that you'd essentially need to implement a Transform stream that would keep a list of all the buffers and write them to a piped stream on a rewind method.

Take a look at the node API for streams here, the methods should look somewhat like this.

class Rewindable extends Transform {

  constructor() {
    super();
    this.accumulator = [];
  }

  _transform(buf, enc, cb) { 
    this.accumulator.push(buf);
    callback()
  }

  rewind() {
    var stream = new PassThrough();
    this.accumulator.forEach((chunk) => stream.write(chunk))
    return stream;
  }

And you would use this like this:

var readStream = fs.createReadStream('proxy.txt');
var rewindableStream = readStream.pipe(new Rewindable());

(...).on("whenerver-you-want-to-reset", () => {
    var rewound = rewindablesteram.rewind();
    /// and do whatever you like with your stream.
});

Actually I think I'll add this to my scramjet. :)

Edit

I released the logic below in rereadable-stream npm package. The upshot over the stream depicted here is that you can now control the buffer length and get rid of the read data.

At the same time you can keep a window of count items and tail a number of chunks backwards.

like image 107
Michał Karpacki Avatar answered Oct 06 '22 19:10

Michał Karpacki