Closed islishude closed 4 years ago
ReadFull 返回从Reader读取的字节数量和错误信息
ReadFull(r Reader, buf []byte) (n int, err error)
ReadFull 经常出现在其它辅助函数中,比如随机数生成函数 rand.Read
rand.Read
package rand import "io" var Reader io.Reader func Read(b []byte) (n int, err error) { return io.ReadFull(Reader, b) }
除了判断 err 是否不为空之外,经常有代码还会判断这个 n 的长度是否和 b 的长度一样,其实这是没必要的,io.ReadFull 内部保证了如果 err == nil 那么 n == len(b)。
如实现代码所示,如果 Reader 内字节长度小于所需长度那么一定会返回 EOF 错误或者 ErrUnexpectedEOF 错误。
func ReadFull(r Reader, buf []byte) (n int, err error) { return ReadAtLeast(r, buf, len(buf)) } func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error) { if len(buf) < min { return 0, ErrShortBuffer } for n < min && err == nil { var nn int nn, err = r.Read(buf[n:]) n += nn } if n >= min { err = nil } else if n > 0 && err == EOF { err = ErrUnexpectedEOF } return }
使用下面实际代码运行来看,确实不需要判断返回长度
package main import ( "bytes" "fmt" "io" ) func main() { // 无数据 0 EOF { src := bytes.NewReader(make([]byte, 0)) dsc := make([]byte, 40) fmt.Println(io.ReadFull(src, dsc)) } // 数据不够 32 unexpected EOF { src := bytes.NewReader(make([]byte, 32)) dsc := make([]byte, 40) fmt.Println(io.ReadFull(src, dsc)) } // 数据正好 32 <nil> { src := bytes.NewReader(make([]byte, 32)) dsc := make([]byte, 32) fmt.Println(io.ReadFull(src, dsc)) } // 数据更多 32 <nil> { src := bytes.NewReader(make([]byte, 40)) dsc := make([]byte, 32) fmt.Println(io.ReadFull(src, dsc)) } }
ReadFull 返回从Reader读取的字节数量和错误信息
ReadFull 经常出现在其它辅助函数中,比如随机数生成函数
rand.Read
除了判断 err 是否不为空之外,经常有代码还会判断这个 n 的长度是否和 b 的长度一样,其实这是没必要的,io.ReadFull 内部保证了如果 err == nil 那么 n == len(b)。
如实现代码所示,如果 Reader 内字节长度小于所需长度那么一定会返回 EOF 错误或者 ErrUnexpectedEOF 错误。
使用下面实际代码运行来看,确实不需要判断返回长度