包ioutil实现一些I/O实用程序函数
** ReadAll 方法**
外部调用方法, 封装了 readAll, 设置 缓冲片大小为512字节,传参由 2个减少至了一个,
从r 读取器 读取,直到出现错误或EOF并返回它读取的数据。 成功的调用返回errnil,而不是errEOF
因为ReadAll定义为从src读取直到EOF,所以它不会将EOF from read视为要报告的错误。
func ReadAll(r io.Reader) ([]byte, error) {
return readAll(r, bytes.MinRead) // MinRead = 512
// MinRead是Buffer.ReadFrom传递给读取调用的最小片大小。 只要缓冲区中至少有MinRead字节 > r字节,ReadFrom就不会增长底层缓冲区
}
** readAll 内部读取 方法**
从r读取数据直到EOF或遇到error,返回读取的数据和可能的错误。成功的调用返回的err为nil而非EOF。因为本函数定义为读取r直到EOF,它不会将读取返回的EOF视为应报告的错误。
func readAll(r io.Reader, capacity int64) (b []byte, err error) {
var buf bytes.Buffer
// 如果缓冲区溢出,我们将得到 bytes.ErrTooLarge.作为错误返回。其他的恐慌仍然存在
defer func() {
e := recover()
if e == nil {
return
}
if panicErr, ok := e.(error); ok && panicErr == bytes.ErrTooLarge {
err = panicErr
} else {
panic(e)
}
}()
if int64(int(capacity)) == capacity {
buf.Grow(int(capacity))
}
_, err = buf.ReadFrom(r)
return buf.Bytes(), err
}
ReadAll 应用
// 1、open打开文件进行读取,返回*File类型,该类型实现了io.Reader 接口
// 2、 作为 io.Reader 类型传参, 读取该文件,返回出[]byte
// 该方法 内:将 *File类型的file文件操作句柄 转成了 实现了 Closer关闭接口的 具体 nopCloser 结构体实例,然后被当成 io.ReadCloser 接口来返回
// 返回的 nopCloser结构体 本身是io.Reader 实现,又定义了close方法继而实现 Closer关闭接口,所以组合成了 定义的反参: io.ReadCloser 接口
func main() {
file, err := os.Open("C:/GoWorks/src/go_task/hello-word/io/out/file1.txt")
checkErr(err)
fileBytes1, err := ioutil.ReadAll(file)
checkErr(err)
fmt.Println(string(fileBytes1))
}
** ReadFile 方法**
ReadFile 从filename指定的文件中读取数据并返回文件的内容。对err的判断和ReadAll一样。
func ReadFile(filename string) ([]byte, error) {
f, err := os.Open(filename