我想使用包含图像的request.Body(type io.ReadCloser)
。
我不想使用ioutil.ReadAll()
,因为我想将此主体直接写入文件以及想要解码它,所以我只想使用对内容的引用传递给进一步的函数调用,
我尝试创建多个读者实例,例如如下所示
package main
import (
"io/ioutil"
"log"
"strings"
)
func main() {
r := strings.NewReader("some io.Reader stream to be read\n")
a := &r
b := &r
log.Println(ioutil.ReadAll(*a))
log.Println(ioutil.ReadAll(*b))
}
但在第二次调用中它总是导致nil
。
请帮助我如何为同一个读者传递多个单独的参考?
io.Reader
被视为一条小溪。因此,你无法阅读两次。想象一下传入的TCP连接。你无法回避进入的最新情况。
但您可以使用io.TeeReader
复制流:
package main
import (
"bytes"
"io"
"io/ioutil"
"log"
"strings"
)
func main() {
r := strings.NewReader("some io.Reader stream to be read\n")
var buf bytes.Buffer
tee := io.TeeReader(r, &buf)
log.Println(ioutil.ReadAll(tee))
log.Println(ioutil.ReadAll(&buf))
}
关于Go Playground的例子
当你调用ReadAll
时,它将清空缓冲区,因此第二次调用将始终不返回任何内容。你可以做的是保存ReadAll
的结果并在你的函数中重用它。例如:
bytes, _ := ioutil.ReadAll(r);
log.Println(string(bytes))
从技术上讲,在一个阅读器上,您无法多次阅读。
这将打印两次。
package main
import (
"io/ioutil"
"log"
"strings"
)
func main() {
r := strings.NewReader("some io.Reader stream to be read\n")
stringData, _ := ioutil.ReadAll(r)
log.Println(stringData)
log.Println(stringData)
}
@TheHippo答案是正确的我只是想添加它(但无法添加它,因为我只有49个声誉:():首先使用TeeReader并在使用缓冲区之后重要信息,否则第二个缓冲区将为空。