2016-09-30 101 views
5

我想使用request.Body(type io.ReadCloser)它包含一個圖像。Golang從同一個閱讀器多次閱讀

我不想使用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

請幫助我如何通過多個單獨的參考爲同一讀者?

+3

撤消你問的方式

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

例。使用'io.TeeReader'來捕獲您閱讀的內容以供進一步參考,例如在'bytes.Buffer'中。 – Volker

回答

3

當你呼叫ReadAll它將清空緩衝區,所以第二個呼叫將永遠不會返回任何內容。你可以做的是保存ReadAll的結果並在你的函數中重用。例如:

bytes, _ := ioutil.ReadAll(r); 
log.Println(string(bytes)) 
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) 
} 
+0

我想知道爲什麼不能:-) –

+2

@AbhishekSoni:'io.Reader'是一個流。一旦你完成了流,沒有更多。如果你閱讀了一部分流,下一次閱讀繼續你離開的地方。 – JimB

8

io.Reader被視爲流。正因爲如此,你不能讀它兩次。想象一下傳入的TCP連接。你不能倒帶什麼在未來

但是你可以使用io.TeeReader複製流:上Go Playground