summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/pkg/io/utils.go18
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.