可读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
。
之后,我根据输出结果提出了几个问题:
- 为什么我得到
abc\ndef\nghi
作为我的第一个testing的输出? 我问这是因为即使在推送abcdefghi
到stream后,它的缓冲区长度仍然是9.所以如果我在任何给定的时间读取,读取操作应该返回null
。 可以肯定的是,我将读取大小设置为300。 - stream如何知道我完成了所有的推动?
当试图重现您的问题时,我认为您已经恢复了默认暂停的process.stdin
stream。 后来我发现,当离开那一点时,我得到了你得到的意想不到的输出。 这就是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
在恢复stdin
stream后进行testing时, readable
会触发四次,并正确read(300)
返回null
。