[英]golang reader.Read() can arrived EOF, but reader.ReadAt() read same data in dead loop way, not arrived EOF?
我正在尝试学习io.Reader.Read()
和io.Reader.ReadAt()
中的差异; 我写了两个例子,第一个是io.Reader.Read()
:
reader := strings.NewReader("some text heresome text heres, ome text heresome text heresome text here")
buf := make([]byte, 64)
i := 0
for {
i++
if i > 10 {
break
}
n, err := reader.Read(buf)
if n > 0 {
fmt.Println(string(buf[:n]))
}
fmt.Println(err)
if err == io.EOF {
fmt.Println("All content is over...")
break
} else if err != nil {
panic(err.Error())
}
}
output 是:
some text heresome text heres, ome text heresome text heresome t
<nil>
ext here
<nil>
EOF
All content is over...
第二个示例只是将Read()
替换为ReadAt()
:
reader := strings.NewReader("some text heresome text heres, ome text heresome text heresome text here")
buf := make([]byte, 64)
i := 0
for {
i++
if i > 10 {
break
}
n, err := reader.ReadAt(buf, 2)
if n > 0 {
fmt.Println(string(buf[:n]))
}
fmt.Println(err)
if err == io.EOF {
fmt.Println("All content is over...")
break
} else if err != nil {
panic(err.Error())
}
}
结果意外没有到达EOF,如果我取消次数限制,就会发生深度循环:output:
me text heresome text heres, ome text heresome text heresome tex
<nil>
me text heresome text heres, ome text heresome text heresome tex
<nil>
me text heresome text heres, ome text heresome text heresome tex
<nil>
me text heresome text heres, ome text heresome text heresome tex
<nil>
me text heresome text heres, ome text heresome text heresome tex
<nil>
me text heresome text heres, ome text heresome text heresome tex
<nil>
me text heresome text heres, ome text heresome text heresome tex
<nil>
me text heresome text heres, ome text heresome text heresome tex
<nil>
me text heresome text heres, ome text heresome text heresome tex
<nil>
me text heresome text heres, ome text heresome text heresome tex
<nil>
我预计第二个示例代码 output 与第一个代码示例类似,只是偏移 2 个字节。 但为什么代码进入死循环?
使用其Read()
方法从io.Reader
读取,读取器的内部指针(偏移量)前进读取(返回)字节数。 下一个Read()
调用将从新的、调整后的偏移量中读取字节。
当您调用ReadAt()
方法时,您明确提供要读取的偏移量,不使用io.Reader
的内部指针/偏移量。 而且由于您读入的缓冲区小于源读取器的可用数据(从给定的偏移量开始),您不会得到io.EOF
,您只需从相同的偏移量读取相同的数据再次。
请注意,如果您增加缓冲区:
buf := make([]byte, 164)
这样,可以将源中可用的所有数据读入其中,并且您将立即获得 EOF(在Go Playground上尝试):
me text heresome text heres, ome text heresome text heresome text here
EOF
All content is over...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.