gitalk icon indicating copy to clipboard operation
gitalk copied to clipboard

从头再读取 io.Reader: 覆水难收?

Open utterances-bot opened this issue 2 years ago • 1 comments

从头再读取 io.Reader: 覆水难收?

前几天,我们百度的同学分享了Go标准库中一段好玩的好玩的代码, net/http/response.go中一段检查HTTP的headser中Content-Length未设置的情况下,对http.Body的有趣的处理。

https://colobu.com/2023/09/24/reread-the-io-Reader/

utterances-bot avatar Sep 25 '23 02:09 utterances-bot

我个人对此情况有以下理解:

覆水难收不能算是 io.Reader 的锅,应该是所有流式 IO 都是有状态有偏移量的,如过不记录偏移量,那下面这个代码永远跳不出 for 循环:

func readAll(r io.Reader) {
	buf := make([]byte, 1024)
	for {
		r.Read(buf)
	}
}

如果可以重复读,那么从网络中已经读了 1000G 想回溯到第一个字节重新读,这 1000G 总得有个地方存。尽管一些语言可能提供了可重复读取的功能,那也只是对 IO 的封装工具类,并且重读能力有限,多数要按需定制,对已读数据的缓存大小需要考量。

xmx avatar Sep 25 '23 02:09 xmx