英文:
Why does an io.reader become empty after reading it?
问题
func foo(buf *bytes.Buffer) {
fmt.Println("0: ", len(buf.Bytes()))
ioutil.ReadAll(buf)
fmt.Println("1: ", len(buf.Bytes()))
}
这段代码第一次显示了正确的长度,但第二次显示长度为零。
英文:
func foo(buf *bytes.Buffer) {
fmt.Println("0: ", len(buf.Bytes()))
ioutil.ReadAll(buf)
fmt.Println("1: ", len(buf.Bytes()))
}
The code shows the correct length the first time, but the second times it shows the length is zero.
答案1
得分: 10
从bytes.Buffer
中读取会消耗或使用已读取的字节。这意味着如果你尝试再次读取,这些字节将不会被返回。
Buffer.Bytes()
返回缓冲区中未读取的部分,所以在所有内容都被读取后,你会看到长度为0
的结果(这正是ioutil.ReadAll()
的作用)。
如果你只想“窥视”而不是真正“读取”字节,该怎么办?
bytes.Buffer
中没有“窥视”功能。最简单的方法是获取缓冲区的字节,并从中构建另一个bytes.Buffer
来进行读取。
代码可能如下所示:
func peek(buf *bytes.Buffer, b []byte) (int, error) {
buf2 := bytes.NewBuffer(buf.Bytes())
return buf2.Read(b)
}
peek()
的使用示例:
为简单起见,省略了错误检查:
buf := &bytes.Buffer{}
buf.WriteString("Hello")
fmt.Printf("Len: %d, Content: %s\n", buf.Len(), buf)
fmt.Println("\nPeeking...")
data := make([]byte, 4)
peek(buf, data)
fmt.Printf("Peeked: %s\n", data)
fmt.Printf("Len: %d, Content: %s\n", buf.Len(), buf)
fmt.Println("\nReading...")
data = make([]byte, buf.Len())
buf.Read(data)
fmt.Printf("Read: %s\n", data)
fmt.Printf("Len: %d, Content: %s\n", buf.Len(), buf)
输出结果(在Go Playground上尝试):
Len: 5, Content: Hello
Peeking...
Peeked: Hell
Len: 5, Content: Hello
Reading...
Read: Hello
Len: 0, Content:
英文:
Reading from a bytes.Buffer
drains or consumes the bytes that were read. This means if you try to read again, those will not be returned.
Buffer.Bytes()
returns the unread portion of the buffer, so it is the expected result for you to see 0
length after everything has been read (this is exactly what ioutil.ReadAll()
does).
What if you just want to "peek" and not really "read" bytes?
There is no "peek" functionality in bytes.Buffer
. The easiest would be to get the bytes of the buffer, and construct another bytes.Buffer
from it and read from the new buffer.
It could look something like this:
func peek(buf *bytes.Buffer, b []byte) (int, error) {
buf2 := bytes.NewBuffer(buf.Bytes())
return buf2.Read(b)
}
peek()
in action:
Error checks omitted for simplicity:
buf := &bytes.Buffer{}
buf.WriteString("Hello")
fmt.Printf("Len: %d, Content: %s\n", buf.Len(), buf)
fmt.Println("\nPeeking...")
data := make([]byte, 4)
peek(buf, data)
fmt.Printf("Peeked: %s\n", data)
fmt.Printf("Len: %d, Content: %s\n", buf.Len(), buf)
fmt.Println("\nReading...")
data = make([]byte, buf.Len())
buf.Read(data)
fmt.Printf("Read: %s\n", data)
fmt.Printf("Len: %d, Content: %s\n", buf.Len(), buf)
Output (try it on the Go Playground):
Len: 5, Content: Hello
Peeking...
Peeked: Hell
Len: 5, Content: Hello
Reading...
Read: Hello
Len: 0, Content:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论