// readAll reads from r until an error or EOF and returns the data it read
// from the internal buffer allocated with a specified capacity.
func readAll(r io.Reader, capacity int64) (b []byte, err error) {
- buf := bytes.NewBuffer(make([]byte, 0, capacity))
+ var buf bytes.Buffer
// If the buffer overflows, we will get bytes.ErrTooLarge.
// Return that as an error. Any other panic remains.
defer func() {
panic(e)
}
}()
+ if int64(int(capacity)) == capacity {
+ buf.Grow(int(capacity))
+ }
_, err = buf.ReadFrom(r)
return buf.Bytes(), err
}
defer f.Close()
// It's a good but not certain bet that FileInfo will tell us exactly how much to
// read, so let's try it but be prepared for the answer to be wrong.
- var n int64
+ var n int64 = bytes.MinRead
if fi, err := f.Stat(); err == nil {
- // Don't preallocate a huge buffer, just in case.
- if size := fi.Size(); size < 1e9 {
+ // As initial capacity for readAll, use Size + a little extra in case Size
+ // is zero, and to avoid another allocation after Read has filled the
+ // buffer. The readAll call will read into its allocated internal buffer
+ // cheaply. If the size was wrong, we'll either waste some space off the end
+ // or reallocate as needed, but in the overwhelmingly common case we'll get
+ // it just right.
+ if size := fi.Size() + bytes.MinRead; size > n {
n = size
}
}
- // As initial capacity for readAll, use n + a little extra in case Size is zero,
- // and to avoid another allocation after Read has filled the buffer. The readAll
- // call will read into its allocated internal buffer cheaply. If the size was
- // wrong, we'll either waste some space off the end or reallocate as needed, but
- // in the overwhelmingly common case we'll get it just right.
- return readAll(f, n+bytes.MinRead)
+ return readAll(f, n)
}
// WriteFile writes data to a file named by filename.