2016-09-30 13 views
5

request.Body(type io.ReadCloser)に画像を含んでいます。私は、ファイルに直接この身体を書くだけでなく、それを解読したいしたいとioutil.ReadAll()を使用したくないので、私は唯一、さらに関数呼び出しに渡すためのコンテンツへの参照を使用したいゴランは同じリーダーから何度も読んでいます

Iは

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

} 

以下の例のためのリーダーの複数のインスタンスを作成しようとしたが、第2の呼び出しでは、常に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を呼び出すと、バッファが空になるので、2番目の呼び出しは常に何も返しません。あなたができることは、ReadAllの結果を保存し、それをあなたの関数に再利用することです。たとえば、

1

技術的には、1つのリーダーで複数回読むことはできません。あなたが別の参照を作成した場合でも

  • しかし
  • それはすべての参照で参照と同じオブジェクトになります一度お読みください。
  • あなたができることは、コンテンツを読み込んで1つの変数に格納することです。
  • 次に、その変数を必要な回数だけ使用します。

これは2回印刷されます。

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はストリームのように処理されます。このため、2度読むことはできません。入ってくるTCP接続を想像してみてください。 。あなたは

に来ていただきましたを巻き戻すことはできませんしかし、あなたは、ストリーム複製する io.TeeReaderを使用することができます: Go Playground

関連する問題