diff --git a/src/pkg/io/ioutil/ioutil.go b/src/pkg/io/ioutil/ioutil.go index fb3fdcda1e6..7e3b44e55c5 100644 --- a/src/pkg/io/ioutil/ioutil.go +++ b/src/pkg/io/ioutil/ioutil.go @@ -13,11 +13,17 @@ import ( "sort" ) +// 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) ([]byte, os.Error) { + buf := bytes.NewBuffer(make([]byte, 0, capacity)) + _, err := buf.ReadFrom(r) + return buf.Bytes(), err +} + // ReadAll reads from r until an error or EOF and returns the data it read. func ReadAll(r io.Reader) ([]byte, os.Error) { - var buf bytes.Buffer - _, err := io.Copy(&buf, r) - return buf.Bytes(), err + return readAll(r, bytes.MinRead) } // ReadFile reads the file named by filename and returns the contents. @@ -34,16 +40,12 @@ func ReadFile(filename string) ([]byte, os.Error) { if err == nil && fi.Size < 2e9 { // Don't preallocate a huge buffer, just in case. n = fi.Size } - // Add a little extra in case Size is zero, and to avoid another allocation after - // Read has filled the buffer. - n += bytes.MinRead - // Pre-allocate the correct size of buffer, then set its size to zero. The - // Buffer will read into the allocated space cheaply. If the size was wrong, - // we'll either waste some space off the end or reallocate as needed, but + // 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. - buf := bytes.NewBuffer(make([]byte, 0, n)) - _, err = buf.ReadFrom(f) - return buf.Bytes(), err + return readAll(f, n+bytes.MinRead) } // WriteFile writes data to a file named by filename.