我有一个简单的函数,可以将
io.Reader
中的内容读取到字节切片中:
func ReadSomething(r io.Reader) {
bufReader := bufio.NewReader(r)
buf := make([]byte, 1024)
bufReader.Read(buf)
...
}
如您所见,要使用缓冲读取,它将接受的
io.Reader
用 bufio.Reader
包装起来。
但是,
bufio.Reader
本身是可以被该函数接受的io.Reader
的实现。由于该函数不知道它到底收到了什么,因此可能导致 bufio.Reader
的嵌套使用。
我考虑过将
r
的类型改为bufio.Reader
,强制要求上层进行包装,这样我的函数就可以直接使用它,但由于包装可能是一个重复的工作,我认为最好让它保持在较低的水平。
在我的例子中,有什么好主意可以避免嵌套使用
bufio.Reader
吗?
bufio.NewReader()
的来源,您会发现这已经得到解决。
NewReader()
使用默认缓冲区大小(4096 字节)调用 NewReaderSize()
。 NewReaderSize()
检查要读取的 io.Reader
是否已经是 bufio.Reader
。如果是,并且该缓冲读取器上的缓冲区大小至少与所需大小一样大,则它不会将 bufio.Reader
包裹在 io.Reader
周围,而是返回 io.Reader
本身。
即如果要嵌套的读取器的缓冲区大小小于默认值(4096 字节),
NewReader()
只会将一个 bufio.Reader
嵌套在另一个 bufio.Reader
周围,以避免返回缓冲区小于要求的缓冲区的读取器。
文档中提到了这一点,但仅限于
NewReaderSize()
;它也适用于 NewReader()
,尽管这没有明确记录,但在代码中很明显。