go - bufio.NewScanner(r) 从 r 调用 Scan() 耗尽缓冲区
问题描述
我想从同一个阅读器创建 2 个扫描仪r
。但是当Scan()
从第一个扫描仪调用时,它会从 中耗尽缓冲区r
,因此第二个扫描仪正在读取零缓冲区。这是一种常见的行为吗?如何修复它以使第二台扫描仪正确读取原件r
?
r := bytes.NewReader([]byte("ninebytes"))
fmt.Println(r.Len()) // 9
sc1 := bufio.NewScanner(r)
sc1.Scan()
fmt.Printf("scanner1: %s\n", sc1.Text()) // scanner1: ninebytes
// i want create new scanner from r too
fmt.Println(r.Len()) // 0
sc2 := bufio.NewScanner(r)
sc1.Scan()
fmt.Printf("scanner2: %s\n", sc2.Text()) // scanner2:
这是一个玩 golang的例子
这就是我想要做的:从文件中读取特定的行,但是当第二次调用该函数时,r
它被耗尽了。
func readLineScanner(r io.Reader, lineNum int) ([]byte, error) {
sc := bufio.NewScanner(r)
lastLine := 0
for sc.Scan() {
lastLine++
if lastLine == lineNum {
break
}
}
return sc.Bytes(), sc.Err()
}
解决方案
阅读读者通常是一种破坏性的行为。特别是对于 http 请求主体。
tee
相反,您可以创建一个以 unix命令为模型的 tee 阅读器。
修改您给出的示例:
r := bytes.NewReader([]byte("ninebytes"))
var buf bytes.Buffer
tee := io.TeeReader(r, &buf)
sc1 := bufio.NewScanner(tee)
sc1.Scan()
fmt.Printf("scanner1: %s\n", sc1.Text())
sc2 := bufio.NewScanner(&buf)
sc2.Scan()
fmt.Printf("scanner2: %s\n", sc2.Text())
使用 tee 阅读器,当您从中读取时r
,会将这些字节的副本写入buf
,您可以在第二个扫描仪中再次使用它。
推荐阅读
- c# - 如何以编程方式退出正在运行的单元测试(使用 Visual Studio c# 和单元测试框架)
- c# - 像 PDF 签名一样使用 iTextSharp 签署 PDF 表单
- elasticsearch - Logstash 每日索引下个月的日期格式错误
- gitlab - GitLab CI:YAML 未运行
- neo4j - 为什么 Neo4j 检查点时间会随着图形大小的增加而增加?
- javascript - 宿主函数返回后的事件中可用的 JavaScript 局部范围变量。为什么?
- java - 一些Ashot策略有“模拟器”字样,它们之间有什么区别?
- javascript - 使用样式系统(和样式组件)在悬停时减轻当前按钮颜色
- javascript - 使用事件传递安慰信息
- flutter - 我如何知道用户是否取消订阅?