What is the difference between io.TeeReader and io.Copy?

huangapple go评论97阅读模式
英文:

What is the difference between io.TeeReader and io.Copy?

问题

io.TeeReaderio.Copy都从读取器(reader)读取数据,并将其写入写入器(writer)。它们之间有什么区别?

英文:

io.TeeReader and io.Copy both read from a reader and write into a writer. What is the difference?

答案1

得分: 8

io.Copy()函数将数据从源io.Reader复制到目标io.Writer。这就是它的全部功能。复制的数据不会返回给你。

另一方面,io.TeeReader()函数不会自动执行复制操作。它只会返回一个io.Reader,如果你从中读取数据,那么你得到的数据也会被写入到你传递给io.TeeReader()io.Writer中。

io.TeeReader()在需要从读取器复制数据到写入器的同时,还需要访问这些数据进行检查或计算时非常有用。

例如,假设你想将一个io.Reader复制到标准输出,并且你还想计算复制内容的MD5哈希值。你可以像这样实现:

s := "Hello World"

r := io.TeeReader(strings.NewReader(s), os.Stdout)

h := md5.New()
if _, err := io.Copy(h, r); err != nil {
    panic(err)
}

fmt.Printf("\nHash: %x", h.Sum(nil))

这将输出以下结果(在Go Playground上尝试):

Hello World
Hash: b10a8db164e0754105b7a99be72e3fe5

请注意,你也可以使用io.MultiWriter()代替io.TeeReader()来实现相同的效果:

s := "Hello World"

h := md5.New()
mw := io.MultiWriter(h, os.Stdout)
if _, err := io.Copy(mw, strings.NewReader(s)); err != nil {
    panic(err)
}

fmt.Printf("\nHash: %x", h.Sum(nil))

这将输出相同的结果。在Go Playground上尝试这个例子。

英文:

io.Copy() copies data from a source io.Reader to a destination io.Writer. And that's all. You don't get the data that was copied, it's not returned to you.

io.TeeReader() on the other hand does not perform the copy automatically. It just returns you an io.Reader which if you read from, the data you get will also be written to the io.Writer you pass to io.TeeReader().

io.TeeReader() is useful if you need to copy data from a reader to a writer, but you also need the data because you want to inspect it or perform calculations on it.

For example let's say you want to copy an io.Reader to the standard output, but you also want to calculate the MD5 hash of the copied content. You may do it like this:

s := "Hello World"

r := io.TeeReader(strings.NewReader(s), os.Stdout)

h := md5.New()
if _, err := io.Copy(h, r); err != nil {
	panic(err)
}

fmt.Printf("\nHash: %x", h.Sum(nil))

This will output (try it on the Go Playground):

Hello World
Hash: b10a8db164e0754105b7a99be72e3fe5

Note that this can also be achieved using io.MultiWriter() instead of io.TeeReader():

s := "Hello World"

h := md5.New()
mw := io.MultiWriter(h, os.Stdout)
if _, err := io.Copy(mw, strings.NewReader(s)); err != nil {
	panic(err)
}

fmt.Printf("\nHash: %x", h.Sum(nil))

This outputs the same. Try this one on the Go Playground.

huangapple
  • 本文由 发表于 2022年3月18日 15:28:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/71523651.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定