可读流的read方法不返回null

时间:2013-08-19 01:35:40

标签: javascript node.js

readableStream.read(size)的文档说明了

  

如果size bytes不可用,则返回null。

为了测试这个,我做了:

// in test.js
process.stdin.on('readable', function(){
  var d = this.read(30);
  if (d) console.log(d.toString());
});

$ (echo abc; sleep 1; echo def; sleep 1; echo ghi) | node test.js

输出如下:

abc
def
ghi

我希望代码打印null,因为size(30)大于写入的字节。为什么不打印null

根据@ hexacyanide的评论,我重写了下面的代码,并再次运行测试:

process.stdin.on('readable', function() {
  var d = this.read(300);
  if (d === null) {
    console.log("NULL")
  } else {
    console.log(d.toString());
  }
});

process.stdin.on('end', function() {
  console.log('END EVENT')
});

测试输出:

NULL
NULL
NULL
abc
def
ghi

END EVENT

我现在可以理解输出直到3 NULL's 之后我根据输出提出了几个问题:

  1. 为什么我将abc\ndef\nghi作为第一次测试的输出?我问这个是因为即使将abcdefghi推送到流后,其缓冲区长度仍为9.因此,如果我在任何给定时间读取,则读取操作应返回null。可以肯定的是,我将读取大小设置为300。
  2. 小组怎么知道我已经完成了所有推送?

1 个答案:

答案 0 :(得分:1)

尝试重现您的问题时,我认为您已经恢复了process.stdin流,默认情况下会暂停。我后来发现,当把这一点丢掉时,我得到了你得到的意外输出。这就是NodeJS文档所述的内容:

  

默认情况下暂停stdin流,因此必须调用   process.stdin.resume()从中读取。

在添加readable侦听器之前,我刚刚在流上使用了resume()并获得了预期的输出。

我不知道我是否正确,但在您的情况下,我认为每次readable运行echo时都会触发,read()正在读取任何内容在这些情况下,但当stdin关闭时,read()只会读取所有内容。这是我的测试代码和结果:

process.stdin.on('readable', function() {
  console.log('fire');
  console.log(process.stdin.read(300));
}).on('end', function(){
  console.log("END EVENT")
});
然后我按照这样的方式运行了代码:(echo abc; sleep 1; echo def; sleep 1; echo ghi) | node test.js并得到了这些结果:

fire
null
fire
null
fire
null
fire
<Buffer 61 62 63 0a 64 65 66 0a 67 68 69 0a>
END EVENT

在恢复stdin流后进行测试时,readable会触发四次,read(300)会正确返回null