我想使用包含图片的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
。
请帮助我如何为同一个读者传递多个单独的参考文献?
答案 0 :(得分:34)
io.Reader
被视为流。因此,你无法阅读两次。想象一下传入的TCP连接。你无法回避最近的事情。
但您可以使用io.TeeReader
复制流:
$ php composer.phar --version
Composer version 1.2.1 2016-09-12 11:27:19
上的示例
答案 1 :(得分:3)
当你致电ReadAll
时,它将清空缓冲区,因此第二次调用将始终不返回任何内容。你可以做的是保存ReadAll
的结果并在你的函数中重用它。例如:
bytes, _ := ioutil.ReadAll(r);
log.Println(string(bytes))
答案 2 :(得分:1)
从技术上讲,在一个阅读器上,您无法多次阅读。
这将打印两次。
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)
}
答案 3 :(得分:1)
@TheHippo答案是正确的,我只想添加此内容(但无法添加,因为我只有49个信誉:():重要的是,首先使用TeeReader,然后在使用复制信息的缓冲区之后使用否则,第二个缓冲区将为空。
答案 4 :(得分:1)
从ioutil.ReadAll(r)中读取时,内容消失了。您无法第二次阅读。 例如:
var response *http.Response
//Read the content
rawBody, err := ioutil.ReadAll(response.Body)
if err != nil {
t.Error(err)
}
// Restore the io.ReadCloser to it's original state
response.Body = ioutil.NopCloser(bytes.NewBuffer(rawBody))