Golang中TeeReader的Writer输出为空的问题小记
这是一个在工作的时候遇到的TeeReader
的Writer
为空的问题。花了一点时间解决。
并且根据官方示例代码做出一定的调整,发现了一个比较有意思的现象。但是没有什么人说到这个问题。
并且,由于对Golang的流式处理不熟悉,途中遇到了很多的问题。
因此,来对记录一下TeeReader
的解读。
TeeReader
TeeReader的描述
首先放出TeeReader
的源代码。代码比较简单,如下:
func TeeReader(r Reader, w Writer) Reader
type teeReader struct
func (p []byte) (n int, err error)
官方的英文解释如下:
TeeReader returns a Reader that writes to w what it reads from r.
All reads from r performed through it are matched with corresponding writes to w. There is no internal buffering - the write must complete before the read completes.
Any error encountered while writing is reported as a read error.
第一句话对于中文语言者可能没有那么好理解,它的意思其实非常简单:
就是将 r 中的数据读出后同时写入 w 中,然后
teeReader
本身也是可以读取数据的,这样,就相当于复制出了一条数据流。
TeeReader的用法
官方的源代码示例如下:
r := strings.NewReader("some io.Reader stream to be read\n")
var buf bytes.Buffer
tee := io.TeeReader(r, &buf)
printall := func(r io.Reader)
printall(tee)
printall(&buf)
其输出结果可得:
TeeReader为什么Writer为空?
TeeReader
的参数是一个reader和一个writer。但是为什么有时候writer会是空的?
这也是我在实际工作中遇到的一个问题。
这里,我们来把源代码示例的printall
的输出顺序调整一下,如下:
//修改前的
printall(tee)
printall(&buf)
//修改过后的
printall(&buf)
printall(tee)
这个时候输出即可看到,一个输出结果,也就是:
some io.Reader stream to be read
这个时候如果使用reflect.typeOf()
去看他们的输出类型,输出结果为:
*bytes.Buffer: *io.teeReader: some io.Reader stream to be read
因此,可以看得到这里的bytes.Buffer
输出内容为空,但是teeReader
是不空的。
那么为什么会这样呢?
***A:***其实,这是由于teeReader
必须要完成了过后,才会写入到buf
当中。因此,提前写诗没有任何数据的。
这个也符合官方原文的英文解释:
TeeReader returns a Reader that writes to w what it reads from r.
希望对你有用。