gitalk
gitalk copied to clipboard
从头再读取 io.Reader: 覆水难收?
从头再读取 io.Reader: 覆水难收?
前几天,我们百度的同学分享了Go标准库中一段好玩的好玩的代码, net/http/response.go中一段检查HTTP的headser中Content-Length未设置的情况下,对http.Body的有趣的处理。
我个人对此情况有以下理解:
覆水难收不能算是 io.Reader 的锅,应该是所有流式 IO 都是有状态有偏移量的,如过不记录偏移量,那下面这个代码永远跳不出 for 循环:
func readAll(r io.Reader) {
buf := make([]byte, 1024)
for {
r.Read(buf)
}
}
如果可以重复读,那么从网络中已经读了 1000G 想回溯到第一个字节重新读,这 1000G 总得有个地方存。尽管一些语言可能提供了可重复读取的功能,那也只是对 IO 的封装工具类,并且重读能力有限,多数要按需定制,对已读数据的缓存大小需要考量。