首页 > 解决方案 > 如何保存,然后再次提供 io.Reader 类型的数据?

问题描述

我想用gocal通过 HTTP 调用检索到的数据解析几次。由于我想避免对每个解析进行调用,我想保存这些数据并重用它。

Body我得到的http.Get类型是io.ReadCloser. gocal解析器需要它io.Reader才能工作。

由于我只能检索Body一次,因此可以将其保存,body, _ := io.ReadAll(get.Body)但后来我不知道如何[]byte作为io.Reader返回(对gocal解析器,多次以考虑不同的解析条件)

标签: go

解决方案


正如您所想的那样,它http.Response.Body被公开为io.Reader,这个阅读器不可重用,因为它直接连接到底层连接*(可能是tcp / utp / 或任何其他流,如net包下的阅读器)。一旦您从连接中读取字节,新字节就会等待另一次读取。

实际上,为了保存响应,您需要先将其排空,然后将结果保存在变量中。

body, _ := io.ReadAll(get.Body)

为了使用 Go 编程语言多次重复使用该字节片,标准 API 提供了缓冲读取器bytes.NewReader

该缓冲区充分提供了Reset([]byte)重置缓冲区状态的方法。

bytes.Reader.Reset对于在没有分配的情况下多次读取相同的字节缓冲区非常有用。相比之下,bytes.NewReader每次调用时都会分配。

最后,在两次连续调用之间c.Parser,您应该使用之前收集的字节缓冲区重置缓冲区。

如 :

buf := bytes.NewReader(body)
// initialize the parser
c.Parse()
// process the result

// reset the buf, parse again
buf.Reset(body)
c.Parse()

你可以试试这个版本https://play.golang.org/p/YaVtCTZHZEP它使用了strings.NewReader缓冲区,但是界面和行为都差不多。

  • 不是很明显,这是一般原则,传输读取标题,并且除非您使用它,否则不要触及正文。另见

推荐阅读