6
6
package ioutil
7
7
8
8
import (
9
- "bytes"
10
9
"io"
11
10
"io/fs"
12
11
"os"
13
12
"sort"
14
- "sync"
15
13
)
16
14
17
- // readAll reads from r until an error or EOF and returns the data it read
18
- // from the internal buffer allocated with a specified capacity.
19
- func readAll (r io.Reader , capacity int64 ) (b []byte , err error ) {
20
- var buf bytes.Buffer
21
- // If the buffer overflows, we will get bytes.ErrTooLarge.
22
- // Return that as an error. Any other panic remains.
23
- defer func () {
24
- e := recover ()
25
- if e == nil {
26
- return
27
- }
28
- if panicErr , ok := e .(error ); ok && panicErr == bytes .ErrTooLarge {
29
- err = panicErr
30
- } else {
31
- panic (e )
32
- }
33
- }()
34
- if int64 (int (capacity )) == capacity {
35
- buf .Grow (int (capacity ))
36
- }
37
- _ , err = buf .ReadFrom (r )
38
- return buf .Bytes (), err
39
- }
40
-
41
15
// ReadAll reads from r until an error or EOF and returns the data it read.
42
16
// A successful call returns err == nil, not err == EOF. Because ReadAll is
43
17
// defined to read from src until EOF, it does not treat an EOF from Read
44
18
// as an error to be reported.
19
+ //
20
+ // As of Go 1.16, this function simply calls io.ReadAll.
45
21
func ReadAll (r io.Reader ) ([]byte , error ) {
46
- return readAll ( r , bytes . MinRead )
22
+ return io . ReadAll ( r )
47
23
}
48
24
49
25
// ReadFile reads the file named by filename and returns the contents.
@@ -58,7 +34,8 @@ func ReadFile(filename string) ([]byte, error) {
58
34
defer f .Close ()
59
35
// It's a good but not certain bet that FileInfo will tell us exactly how much to
60
36
// read, so let's try it but be prepared for the answer to be wrong.
61
- var n int64 = bytes .MinRead
37
+ const minRead = 512
38
+ var n int64 = minRead
62
39
63
40
if fi , err := f .Stat (); err == nil {
64
41
// As initial capacity for readAll, use Size + a little extra in case Size
@@ -67,11 +44,30 @@ func ReadFile(filename string) ([]byte, error) {
67
44
// cheaply. If the size was wrong, we'll either waste some space off the end
68
45
// or reallocate as needed, but in the overwhelmingly common case we'll get
69
46
// it just right.
70
- if size := fi .Size () + bytes . MinRead ; size > n {
47
+ if size := fi .Size () + minRead ; size > n {
71
48
n = size
72
49
}
73
50
}
74
- return readAll (f , n )
51
+
52
+ if int64 (int (n )) != n {
53
+ n = minRead
54
+ }
55
+
56
+ b := make ([]byte , 0 , n )
57
+ for {
58
+ if len (b ) == cap (b ) {
59
+ // Add more capacity (let append pick how much).
60
+ b = append (b , 0 )[:len (b )]
61
+ }
62
+ n , err := f .Read (b [len (b ):cap (b )])
63
+ b = b [:len (b )+ n ]
64
+ if err != nil {
65
+ if err == io .EOF {
66
+ err = nil
67
+ }
68
+ return b , err
69
+ }
70
+ }
75
71
}
76
72
77
73
// WriteFile writes data to a file named by filename.
@@ -105,55 +101,16 @@ func ReadDir(dirname string) ([]fs.FileInfo, error) {
105
101
return list , nil
106
102
}
107
103
108
- type nopCloser struct {
109
- io.Reader
110
- }
111
-
112
- func (nopCloser ) Close () error { return nil }
113
-
114
104
// NopCloser returns a ReadCloser with a no-op Close method wrapping
115
105
// the provided Reader r.
106
+ //
107
+ // As of Go 1.16, this function simply calls io.NopCloser.
116
108
func NopCloser (r io.Reader ) io.ReadCloser {
117
- return nopCloser {r }
118
- }
119
-
120
- type devNull int
121
-
122
- // devNull implements ReaderFrom as an optimization so io.Copy to
123
- // ioutil.Discard can avoid doing unnecessary work.
124
- var _ io.ReaderFrom = devNull (0 )
125
-
126
- func (devNull ) Write (p []byte ) (int , error ) {
127
- return len (p ), nil
128
- }
129
-
130
- func (devNull ) WriteString (s string ) (int , error ) {
131
- return len (s ), nil
132
- }
133
-
134
- var blackHolePool = sync.Pool {
135
- New : func () interface {} {
136
- b := make ([]byte , 8192 )
137
- return & b
138
- },
139
- }
140
-
141
- func (devNull ) ReadFrom (r io.Reader ) (n int64 , err error ) {
142
- bufp := blackHolePool .Get ().(* []byte )
143
- readSize := 0
144
- for {
145
- readSize , err = r .Read (* bufp )
146
- n += int64 (readSize )
147
- if err != nil {
148
- blackHolePool .Put (bufp )
149
- if err == io .EOF {
150
- return n , nil
151
- }
152
- return
153
- }
154
- }
109
+ return io .NopCloser (r )
155
110
}
156
111
157
112
// Discard is an io.Writer on which all Write calls succeed
158
113
// without doing anything.
159
- var Discard io.Writer = devNull (0 )
114
+ //
115
+ // As of Go 1.16, this value is simply io.Discard.
116
+ var Discard io.Writer = io .Discard
0 commit comments