Io 缓冲区外读取

Io 缓冲区外读取,io,go,Io,Go,我有一个大小为bufferSize的缓冲区,我从中读取blockSize块,但是,当blockSize超出bufferSize时,这会产生一些(对我来说)意外的行为 我把代码放在这里: 为什么第二个块只给出4个字节?这里发生了什么事 我希望Read总是给出字节数len(byteArray),如果超出缓冲区,它将通过将缓冲区中的指针设置为afterbyteArray来处理这种情况,并将剩余的缓冲区+超出缓冲区的任何内容放入新的缓冲区指针。您的期望不是基于bufio.Reader的任何记录行为。如

我有一个大小为
bufferSize
的缓冲区,我从中读取
blockSize
块,但是,当
blockSize
超出
bufferSize
时,这会产生一些(对我来说)意外的行为

我把代码放在这里:

为什么第二个块只给出4个字节?这里发生了什么事


我希望
Read
总是给出字节数
len(byteArray)
,如果超出缓冲区,它将通过将缓冲区中的指针设置为after
byteArray
来处理这种情况,并将剩余的缓冲区+超出缓冲区的任何内容放入新的缓冲区指针。

您的期望不是基于
bufio.Reader
的任何记录行为。如果希望“读取总是给出字节数len(byteArray)”,则必须使用


输出:

First read got 12 bytes: some length 
Second read got 12 bytes: test string 

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

复制src是b.buf[b.r:],当您第一次阅读时,b.r=12,…

谢谢,这就是它。这就解释了为什么读取作为一个较低级的函数,也只会达到缓冲区的极限。同样值得检查
io.ReadFull
ioutil.ReadAll
@skinkelynet,我要补充的是,go的基本功能(幸运的)非常低级,同时在需要时提供更多高级实用程序。
io.Read()
不填充整个缓冲区的这一特性实际上与POSIX系统调用的语义相匹配,POSIX系统调用使用其缓冲区大小参数只知道它可以从底层获取并返回的字节的上限;下限为一个字节(用于阻塞调用,0用于非阻塞调用或发生错误)。
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,
    }
}
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
}