Node.js read.read()返回null

Bar*_*Mao 3 node.js

我想从文件中读取字节,这是示例代码:

var fs = require('fs');

var stream= fs.createReadStream('./lib');
console.log(stream.read(10));
Run Code Online (Sandbox Code Playgroud)

返回null。

我认为这是因为read()方法直接从内部缓冲区获取数据。如果缓冲区中的数据不足,null则返回。该read()方法是一个同步调用,没有回调传递,因此设计很有意义。但是我不知道内部缓冲区何时可以有足够的数据,以便我的read()调用可以返回数据,因为它现在处于暂停模式?

更新1:

活动readable是入门的好方法。但是,如果我想读取一个大文件,并且读取计数> 65536,则将返回null。

var fs = require('fs');

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

});
Run Code Online (Sandbox Code Playgroud)

我确切想要的是stream.read()可以始终返回数据,直到EOF。

Tro*_*ott 5

等待readable事件触发,然后尝试读取以下内容:

var fs = require('fs');

var stream= fs.createReadStream('./lib');
stream.on('readable', function () {
  var buffer = stream.read(10);
  if (buffer) {
    console.log(buffer.toString());
  }
});
Run Code Online (Sandbox Code Playgroud)


Bar*_*Mao 5

根据官方文件

一旦内部缓冲区耗尽,当有更多数据可用时,“可读”事件将再次触发。

我可以使用 async/await 以便 readable.read() 总是可以返回数据,只要不在 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();
Run Code Online (Sandbox Code Playgroud)

输出:

begin
10
65535
100000
10
end 
Run Code Online (Sandbox Code Playgroud)

  • 或者只使用“once”而不是“on”来注册一次性侦听器。也不需要将“buf”包装在解析为“buf”值的 Promise 中——如果返回的值还不是一个,“async”函数会将返回值包装在 Promise 中,因此您可以只使用“ if(buf) 返回 buf;`。 (2认同)