可读stream的read方法不返回null

对于readableStream.read(size)的文档说,

如果size字节不可用,那么它将返回null。

为了testing这个我做了:

 // 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的评论,我重写了下面的代码,并再次运行testing:

 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') }); 

testing输出:

 NULL NULL NULL abc def ghi END EVENT 

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

  1. 为什么我得到abc\ndef\nghi作为我的第一个testing的输出? 我问这是因为即使在推送abcdefghi到stream后,它的缓冲区长度仍然是9.所以如果我在任何给定的时间读取,读取操作应该返回null 。 可以肯定的是,我将读取大小设置为300。
  2. stream如何知道我完成了所有的推动?

当试图重现您的问题时,我认为您已经恢复了默认暂停的process.stdinstream。 后来我发现,当离开那一点时,我得到了你得到的意想不到的输出。 这就是NodeJS文档所说的:

标准inputstream默认是暂停的,所以必须调用process.stdin.resume()来读取它。

在添加readable监听器之前,我只是使用了resume()来获得预期的输出。

我不知道我是否正确,但在你的情况下,我假设每次运行echo都可read() ,而read()在这种情况下什么都不读,但是当stdin被closures时, read()只是读一切。 这是我的testing代码和结果:

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

在恢复stdinstream后进行testing时, readable会触发四次,并正确read(300)返回null