2

医生readableStream.read(size)说,

如果 size 字节不可用,则它将返回 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. 流如何知道我已完成所有推送?
4

1 回答 1

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

于 2013-08-19T05:11:37.823 回答