diff options
-rw-r--r-- | src/pkg/io/utils.go | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/src/pkg/io/utils.go b/src/pkg/io/utils.go index ccd611571..0e0b84ae4 100644 --- a/src/pkg/io/utils.go +++ b/src/pkg/io/utils.go @@ -26,7 +26,23 @@ func ReadFile(filename string) ([]byte, os.Error) { return nil, err } defer f.Close(); - return ReadAll(f); + // It's a good but not certain bet that Stat will tell us exactly how much to + // read, so let's try it but be prepared for the answer to be wrong. + dir, err := f.Stat(); + var n uint64; + if err != nil && dir.Size < 2e9 { // Don't preallocate a huge buffer, just in case. + n = dir.Size + } + if n == 0 { + n = 1024 // No idea what's right, but zero isn't. + } + // 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 + // in the overwhelmingly common case we'll get it just right. + buf := bytes.NewBuffer(make([]byte, n)[0:0]); + _, err = Copy(buf, f); + return buf.Bytes(), err; } // WriteFile writes data to a file named by filename. |