Search code examples
gobuffer

How to avoid nested using of bufio.Reader or bufio.Writer


I have a simple function which read something from a io.Reader into a byte slice:

func ReadSomething(r io.Reader) {
    bufReader := bufio.NewReader(r)
    buf := make([]byte, 1024)
    bufReader.Read(buf)
    ...
}

As you can see, to use buffered reading, it wraps the accepted io.Reader with bufio.Reader.

However, bufio.Reader itself is an implementation of io.Reader that can be accepted by this function. Since this function has no awareness of what exactly it received, it is possible to lead to nested using of bufio.Reader.

I have considered changing the type of r to bufio.Reader to forcibly ask upper levels to do the wrapping so my function can just use it as is, but since the wrapping can be a repeatedly work, I think it is better to leave it to lower levels.

Is there any good ideas to avoid nested using of bufio.Reader in my case?


Solution

  • If you check the source for bufio.NewReader() you will find that this is already taken care of.

    NewReader() calls NewReaderSize() with the default buffer size (4096 bytes). NewReaderSize() checks to see if the io.Reader to be read is already a bufio.Reader. If it is, and if the buffer size on that buffered reader is at least as large as the desired size then instead of wrapping a bufio.Reader around the io.Reader, it just returns the io.Reader itself.

    i.e. NewReader() will only nest a bufio.Reader around another bufio.Reader if the reader to be nested has a buffer size smaller than the default (4096 bytes), to avoid returning a buffered reader with a smaller buffer than asked for.

    This is mentioned in the documentation, but only for NewReaderSize(); it also applies to NewReader() though this is not explicitly documented but is evident in the code.