Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nodejs readable.read() return null

Tags:

node.js

I want read bytes from a file, here is the sample code:

var fs = require('fs');

var stream= fs.createReadStream('./lib');
console.log(stream.read(10));

return null.

I think it's because read() method directly get data from the inner buffer. If the buffer has not enough data, the null is returned. The read() method is a sync call, no callback being passed, so that design makes sense. However I don't know when the inner buffer can have enough data so that my read() call can return data since it's paused mode now?

Update1:

event readable is a good way to get started. But if I want to read a large file, and the read count > 65536, null will return.

var fs = require('fs');

var stream = fs.createReadStream('./lib');
stream.on('readable', function () {
    var buffer = stream.read(65537);
    console.log(buffer.length);

});

What I want exactly is stream.read() can always return data till the EOF.

like image 674
BartMao Avatar asked Jan 05 '17 05:01

BartMao


People also ask

How do you change modes in readable stream mode?

All readable streams start in the paused mode by default. One of the ways of switching the mode of a stream to flowing is to attach a 'data' event listener. A way to switch the readable stream to a flowing mode manually is to call the stream. resume method.

What is a readStream?

A readable stream is an abstraction for a source from which data can be consumed. An example of that is the fs. createReadStream method. A writable stream is an abstraction for a destination to which data can be written.

What is stream PassThrough ()?

PassThrough. This Stream is a trivial implementation of a Transform stream that simply passes the input bytes across to the output. This is mainly for testing and some other trivial use cases. Here is an example of Passthrough Stream where it is piping from readable stream to writable stream.

Which of the following is true about a readable stream?

Q 4 - Which of the following is true about readable stream? A - Readable stream is used for read operation.


2 Answers

Wait for the readable event to fire before trying to read:

var fs = require('fs');

var stream= fs.createReadStream('./lib');
stream.on('readable', function () {
  var buffer = stream.read(10);
  if (buffer) {
    console.log(buffer.toString());
  }
});
like image 176
Trott Avatar answered Sep 17 '22 03:09

Trott


According to the official document:

Once the internal buffer is drained, a 'readable' event will fire again when more data is available.

I can use async/await so that readable.read() can always return data as long as not at the EOF.

let rs = fs.createReadStream('./resources/1.gif');

async function readable(): Promise<{}> {
    return new Promise(r => rs.on('readable', r));
}

async function readBytes(num: number = 0): Promise<Buffer> {
    let buf = rs.read(num);
    if (buf) {
        return new Promise<Buffer>(r => r(buf));
    }
    else {
        return new Promise<Buffer>(r => {
            this.readable().then(() => {
                this.readBytes(num).then(b => r(b));
            });
        });
    }
}

async function main() {
    console.log('begin');
    console.log((await readBytes(10)).length);
    console.log((await readBytes(65535)).length);
    console.log((await readBytes(100000)).length);
    console.log((await readBytes(10)).length);
    console.log('end');
}

main();

Outputs:

begin
10
65535
100000
10
end 
like image 41
BartMao Avatar answered Sep 20 '22 03:09

BartMao