首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从同一个io.Reader多次读取

如何从同一个io.Reader多次读取
EN

Stack Overflow用户
提问于 2016-09-30 11:58:32
回答 5查看 45.1K关注 0票数 75

我想使用request.Body(type io.ReadCloser),它包含一个图像。

我不想使用ioutil.ReadAll(),因为我想将这个正文直接写到文件中,也不想解码它,所以我只想使用对内容的引用传递给进一步的函数调用,

我尝试创建多个阅读器实例,例如,如下所示

代码语言:javascript
复制
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

请帮助我如何为同一个读者传递多个单独的引用?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2016-09-30 12:58:05

io.Reader被视为一条溪流。正因为如此,你不能读两遍。想象一个传入的TCP连接--您不能倒带即将到来的内容。

但是可以使用io.TeeReader复制流:

代码语言:javascript
复制
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)) 
}

围棋游乐场上的实例

编辑:( @mrclx )指出:您需要先从TeeReader读取,否则缓冲区将为空。

票数 130
EN

Stack Overflow用户

发布于 2016-09-30 12:02:33

当您调用ReadAll时,它将清空缓冲区,因此第二个调用将始终不返回任何内容。您可以做的是保存ReadAll的结果并在您的函数中重用它。例如:

代码语言:javascript
复制
bytes, _ := ioutil.ReadAll(r);
log.Println(string(bytes))
票数 9
EN

Stack Overflow用户

发布于 2020-02-06 15:20:57

那么,当您从ioutil.ReadAll(r)读取时,内容就消失了。你不能再读一遍了。举个例子:

代码语言:javascript
复制
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))
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39791021

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档