如何从io.reader读取数据?
我正在学习go bufio软件包,并因下面的代码段而混淆:
1 s1 := strings.NewReader(strings.Repeat("a", 16) + strings.Repeat("b", 16))
2 r := bufio.NewReaderSize(s1, 16)
3 b, _ := r.Peek(3)
4 fmt.Printf("%q\n", b)
5 r.Read(make([]byte, 16))
6 r.Read(make([]byte, 15))
7 fmt.Printf("%q\n", b)
// "aaa"
// "bbb"
第2行中的r
是一个空的[]字节吗?为什么用户r.peek(3)
可以找出“ AAA”结果?
假设bufio.newreadersize(s1,16)
可以读取读者s1
的16个字节,这使第3行合理;为什么在LINE5和LINE6中使用两次R.Read()?
难道不是第5行中r
的非属性数组是“ aaaaaaaaaaaaaaa”,而LINE6成为“ BBBBBBBBBBBBBBBBBBB”?
Or maybe the underlying array of r
always be "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb"?
如果您能给我任何灵感,请感谢您的帮助。
I'm learning for Go bufio package, and confused by a code snippet below:
1 s1 := strings.NewReader(strings.Repeat("a", 16) + strings.Repeat("b", 16))
2 r := bufio.NewReaderSize(s1, 16)
3 b, _ := r.Peek(3)
4 fmt.Printf("%q\n", b)
5 r.Read(make([]byte, 16))
6 r.Read(make([]byte, 15))
7 fmt.Printf("%q\n", b)
// "aaa"
// "bbb"
Isn't that r
in line 2 an empty []byte? Why can user r.Peek(3)
to figure out the "aaa" result?
Assume the bufio.NewReaderSize(s1, 16)
can Read 16 bytes from Reader s1
, this make line 3 reasonable; Why use twice r.Read() in line5 and line6?
And Isn't that the undelying array of r
in line 5 is "aaaaaaaaaaaaaaaa", and line6 became the "bbbbbbbbbbbbbbb"?
Or maybe the underlying array of r
always be "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb"?
If you can give me any inspiration, Thank you for your help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果下面的缓冲区是空的或没有足够的空间来满足PEEK(n),则Bufio.Reader将调用其基础io.Reader读取方法以填充缓冲区,您可以通过从PEEK中扩展返回的切片, > b,_:= r.peek(1); fmt.printf(“%q \ n”,b [:cap(b)])。
问题是您正在滥用软件包,无法保证或API可以获取基础数组,甚至使用它已使用,Peek返回了切片中的基础数组,只是避免了复制/内存分配,实际上Bufio可能只是Bufio可能只是忽略缓冲并直接致电基础阅读器,请参见: https://go.dev/play/play/play/pplay/pplay/p/wt6aufeno3tt
如PEEK文档中指出的那样,从PEEK返回的切片仅是有效的值,直到呼叫读取,以正确获取读者的数据,使用读取方法,而不是技巧来获取其基础缓冲区。
If the underlying buffer is empty or has not enough space left to satisfy Peek(n), bufio.Reader will call its underlying io.Reader Read method to fill the buffer, you can check this by extending the returned slice from Peek,
b , _ := r.Peek(1); fmt.Printf("%q\n", b[:cap(b)])
.The problem is that you're misusing the package, there is no guarantee nor API to get the underlying array or even that it's used, Peek returns the underlying array in a slice only to avoid a copy/memory allocation, in fact bufio may just ignore buffering and call the underlying reader directly, see: https://go.dev/play/p/WT6AUfEno3t
As noted in Peek documentation, the returned slice from Peek is only valid values until a call to Read, to correctly get data from Reader, use the Read method, not tricks to get its underlying buffer.