可读流从底层数据源获得数据高于highWaterMark的情况下,会直接丢弃接下来获得的底层数据吗?
发布于 4 年前 作者 linxiaoziruo 5309 次浏览 来自 问答

可读流从底层数据源获得数据高于highWaterMark的情况下,会直接丢弃接下来获得的底层数据吗?

6 回复

image.png

理解没有出错的话,貌似这个 fs.read 里的 length 就是 stream 中的 HighWaterMark。

如果成立的话楼主的问题貌似可以换成,如果 read 的 length 小于实际的大小,剩下的是不是没有了?

@lellansin 我的理解是HighWaterMark表示的是buffer的大小,如果超过这个大小,会触发一系列的反应。每次读取的length是人为指定的,可以超过HighWaterMark,也可以小于HighWaterMark,fs.read 里的 length不一定就是HighWaterMark。我没想明白的是,如果指定的length超过了HighWaterMark,超过的这部分是直接丢弃吗?

@linxiaoziruo TCP 协议有个 ack 机制,就是确认了之后再发下一阶段的包,如果没有 ack 到了一定时间会重发。所以从这个角度来看,如果 TCP 协议发送的数据过多,有包没有在额定的时间内被接收方 ack,那么发送方就会重发。也就是说,如果这个是一个 TCP 之类的 socket stream。那么,这个没有被读取的数据可能是被缓存也可能是丢了等待重发,anyway,你可以写几个 case 验证一下。理论上来说,这些不属于应用层应该关心的。

HighWaterMark 跟buffer没有关系哦 HighWaterMark是一次读取Buffer的大小 buffer是读取后要放置的buffer length是你要读多少放到buffer中

HighWaterMark 只是一个标识位,具体怎么做还是由 stream 本身决定的 像 fs 中都是当缓冲 buffer 长度达到 HighWaterMark 时就停止读取了,所以 node 可以用很少的内存读取很大的文件 当然,如果非要一次性读取个几 G 的文件到内存,也没人能拦着你。。 fs.read() 这个 api 跟 HighWaterMark 没啥关系

好像回错帖子了 自己写个流没处理好会丢数据,但这也是你自己丢的


结论: 不一定会 为什么: 这段时间的数据会被缓存,知道缓存的数据大于HighWaterMark就会暂停从底层读取数据,这时候数据会堆积底层 底层也有接收缓存:当缓存渐渐不够用的时候,会阻止接受数据,这时候数据会堆积在发送侧 发送也有发送缓存: 当缓存渐渐不够用的时候,会发送失败,如果发送方没有正确处理,可能会丢失数据

回到顶部