题目解答见:练习题答案
其余部分为相关只是补充
题目:
io包里面的LimitReader函数
io.Reader是一个接口,任何实现了Read()函数的对象,都可以作为Reader来使用
type Reader interface{
Read(p []byte) (n int, err error)
}
strings.NewReader实现了将一个普通的字符串创建一个Reader
下面是创建的源码:
Reader的结构体
type Reader struct {
s string //资源 : 要读取的字符串
i int64 // current reading index
prevRune int // index of previous rune; or < 0
}
i
: 一个对象并不是一次性读完,i用来记录每次读到了哪里实现Read()方法
func (r *Reader) Read(b []byte) (n int, err error) {
if r.i >= int64(len(r.s)) { //如果当前index大于s的长度则说明读到了结尾
return 0, io.EOF
}
r.prevRune = -1 //?
n = copy(b, r.s[r.i:]) // 将剩余字符串赋值给b []byte ; n = 复制了多少个字符
r.i += int64(n) //r 读走了b的长度这么多个字符
return
}
n = copy(b, r.s[r.i:])
: 将从最初位子r.i 到末尾位子len(b)+ r.i复制过去,并返回复制了多少个字符
这里copy(b,...)
可以从外面获取到b, 引用传递r.i 读取位子后移
使用NewReader() 读取一个字符串为Reader,
Reader使用Read()方法每次读取p个字符
// 根据原始的io.Reader创建一个字符读取器
reader := strings.NewReader("123456789")
p := make([]byte, 2) // 选择每次读取多少个字符
// 每次读取两个字符,直到读取完毕为止
for {
n, err := reader.Read(p)
if err != nil { // 读取出错or到了结尾
if err == io.EOF {
fmt.Println("读到结尾啦")
break
}
fmt.Println("出错")
os.Exit(1)
}
fmt.Printf("本次读取内容 %s , %d\n", p[:], n) // 获取到p的内容
}
输出
本次读取内容 12 , 2
本次读取内容 34 , 2
本次读取内容 56 , 2
本次读取内容 78 , 2
本次读取内容 98 , 1
读到结尾啦
io包里面的LimitReader函数
func LimitReader(r io.Reader, n int64) io.Reader
func main() {
r := strings.NewReader("1234567890")
reader := LimitReader(r, 8) // 限制最多一共读取8个字符
p := make([]byte, 2) // 每次读取两个字符
for {
n, err := reader.Read(p)
if err != nil {
if err == io.EOF {
fmt.Println("已经读到结尾!")
break
}
// 读取出错
log.Fatalf("读取出错 %v", err) // equivalent print and call exit()
}
fmt.Printf("本次读取%d个字符 : %s\n", n, p[:])
}
}
type LimitedReader struct {
io.Reader
N int // 最多读取N个字符
}
// 实现Reader里面的Read() : 功能是可以读取n个字符就表示出结束符
func (l *LimitedReader) Read(p []byte) (n int, err error) {
// 结束读取
if l.N <= 0 { // 什么时候会< 0 : 传入的数字本身就<0
err = io.EOF
return
}
if len(p) > l.N { // 可以一次读到结尾
p = p[:l.N] // 减小p的大小为l.N
}
n, err = l.Reader.Read(p)
l.N -= n
return
}
func LimitReader(r io.Reader, n int) io.Reader {
return &LimitedReader{r, n}
}
输出
本次读取2个字符 : 12
本次读取2个字符 : 34
本次读取2个字符 : 56
本次读取2个字符 : 78
已经读到结尾!
func LimitReader(r Reader, n int64) Reader { return &LimitedReader{r, n} }
// A LimitedReader reads from R but limits the amount of
// data returned to just N bytes. Each call to Read
// updates N to reflect the new amount remaining.
// Read returns EOF when N <= 0 or when the underlying R returns EOF.
type LimitedReader struct {
R Reader // underlying reader
N int64 // max bytes remaining
}
func (l *LimitedReader) Read(p []byte) (n int, err error) {
// 判断结尾的标志 : 相当于strings.Reader里面的 i : index 记录当前读到的位子
if l.N <= 0 {
return 0, EOF
}
// p的容量大于N : 一次可以读完
if int64(len(p)) > l.N {
p = p[0:l.N]
}
// 一次不能读完
n, err = l.R.Read(p)
// 当前还能再次读取的字符 :
l.N -= int64(n)
return
}