如何从同一个io.Reader读取多次 [英] How to read multiple times from same io.Reader

查看:761
本文介绍了如何从同一个io.Reader读取多次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要使用包含图像的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)) 
}
 

进入游乐场

上的示例

正如@mrclx所指出的:您需要先从TeeReader读取,否则缓冲区将为空.

I want to use request.Body(type io.ReadCloser) which is containing a image.

I dont want to use ioutil.ReadAll() as i want to write this body directly to the file as well as want to decode it, so i only want to use the reference to the content to pass to further function calls,

I tried creating multiple instances of reader for example shown below

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))

}

but in second call it always results into nil.

Please help me how can i pass multiple separate reference for the same reader?

解决方案

io.Reader is treated like a stream. Because of this you cannot read it twice. Imagine the an incoming TCP connection. You cannot rewind the whats coming in.

But you can use the io.TeeReader to duplicate the stream:

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)) 
}

Example on Go Playground

Edit: As @mrclx pointed out: You need to read from the TeeReader first, otherwise the buffer will be empty.

这篇关于如何从同一个io.Reader读取多次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆