我有一个大小为bufferSize
的缓冲区,我在其中读取blockSize
的块,然而,当blockSize
超出bufferSize
时,会产生一些(对我而言)意外行为{1}}。
我把代码放在这里:
http://play.golang.org/p/Ra2jicYHPu
为什么第二个块只提供4个字节?这里发生了什么?
我希望Read
总是给出字节量len(byteArray)
,如果超出缓冲区,它会通过将缓冲区中的指针设置为{{{}来处理这种情况。 1}},并将缓冲区的其余部分+超出新的缓冲区指针。
答案 0 :(得分:1)
您的期望不是基于bufio.Reader
的任何记录行为。如果你想要“读取总是给出字节数len(byteArray)”,你必须使用io.ReadAtLeast。
package main
import (
"bufio"
"fmt"
"io"
"strings"
)
const bufSize = 10
const blockSize = 12
func main() {
s := strings.NewReader("some length test string buffer boom")
buffer := bufio.NewReaderSize(s, bufSize)
b := make([]byte, blockSize)
n, err := io.ReadAtLeast(buffer, b, blockSize)
if err != nil {
fmt.Println(err)
}
fmt.Printf("First read got %d bytes: %s\n", n, string(b))
d := make([]byte, blockSize)
n, err = io.ReadAtLeast(buffer, d, blockSize)
if err != nil {
fmt.Println(err)
}
fmt.Printf("Second read got %d bytes: %s\n", n, string(d))
}
输出:
First read got 12 bytes: some length
Second read got 12 bytes: test string
答案 1 :(得分:0)
1.查看buffio.NewReaderSize的代码
func NewReaderSize(rd io.Reader, size int) *Reader {
// Is it already a Reader?
b, ok := rd.(*Reader)
if ok && len(b.buf) >= size {
return b
}
if size < minReadBufferSize {
size = minReadBufferSize
}
return &Reader{
buf: make([]byte, size),
rd: rd,
lastByte: -1,
lastRuneSize: -1,
}
}
strings.NewReader返回一个strings.Reader,所以缓冲区(由bufio.NewReaderSize返回)buf有minReadBufferSize(val为16) 2.查看bufio的代码。阅读
func (b *Reader) Read(p []byte) (n int, err error) {
……
copy(p[0:n], b.buf[b.r:])
b.r += n
b.lastByte = int(b.buf[b.r-1])
b.lastRuneSize = -1
return n, nil
}
复制src是b.buf [ b.r :],当你第一次读,b.r = 12,......