Nodejs readable.read()返回null

时间:2017-01-05 05:59:18

标签: node.js

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

var fs = require('fs');

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

返回null。

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

UPDATE1:

事件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);

});

我想要的是stream.read()总能将数据返回到EOF。

4 个答案:

答案 0 :(得分:3)

在尝试阅读前等待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());
  }
});

答案 1 :(得分:3)

根据官方document

  

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

我可以使用async / await,这样只要不在EOF,readable.read()就可以始终返回数据。

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();

输出:

begin
10
65535
100000
10
end 

答案 2 :(得分:1)

如果我可以引用文档中的内容:https://nodejs.org/api/stream.html#stream_readable_read_size

const stream = fs.createReadStream('./lib');
stream.on('readable', () => {
   let chunk;
   while (null !== (chunk = stream.read())) {
      console.log(`Received ${chunk.length} bytes of data.`);
   }
});

答案 3 :(得分:0)

Streams以块的形式读取数据以进行处理。如果您只想获取文件的全部内容,则应使用fs.readFile()

fs.readFile(FILENAME, (err, data) => {
    console.log(Buffer.isBuffer(data));
    console.log(data.length);
})

另一方面,只要有适合您的数据,流就会发出data事件。默认情况下,此流的highWaterMark为64K。

var stream = fs.createReadStream(FILENAME);
var results = []

stream.on('data', function (chunk) {
    // For text files chunk is string
    // for binary files chunk is an instance of Buffer

    // do something with this chunk...

    results.push(`Chunk ${results.length} OK`)
});

stream.on('end', function() {
    console.log(results);
})