读取超出缓冲区

时间:2013-08-27 14:22:27

标签: io go

我有一个大小为bufferSize的缓冲区,我在其中读取blockSize的块,然而,当blockSize超出bufferSize时,会产生一些(对我而言)意外行为{1}}。

我把代码放在这里:

http://play.golang.org/p/Ra2jicYHPu

为什么第二个块只提供4个字节?这里发生了什么?

我希望Read总是给出字节量len(byteArray),如果超出缓冲区,它会通过将缓冲区中的指针设置为{{{}来处理这种情况。 1}},并将缓冲区的其余部分+超出新的缓冲区指针。

2 个答案:

答案 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))
}

Playground


输出:

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,......