2016-09-30 1 views
5

Ich möchte request.Body(type io.ReadCloser) verwenden, die ein Bild enthält.Golang mehrmals vom selben Leser lesen

Ich möchte nicht ioutil.ReadAll() verwenden, wie ich diesen Körper schreiben wollen direkt in die Datei als auch wollen, sie entschlüsseln, so möchte ich nur den Verweis auf den Inhalt verwenden, um weitere Funktionsaufrufe zu passieren,

ich habe versucht, zum Beispiel unter

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

} 

gezeigt mehrere Instanzen von Leser zu schaffen, sondern in der zweiten nennen es führt immer in nil.

Bitte helfen Sie mir, wie kann ich mehrere separate Referenz für den gleichen Leser übergeben?

+3

Undoable die Art und Weise Sie gefragt. Verwenden Sie einen 'io.TeeReader', um zu erfassen, was Sie zur weiteren Bezugnahme gelesen haben, z. in einem 'Bytes.Buffer'. – Volker

Antwort

3

Wenn Sie ReadAll aufrufen, wird der Puffer leer, so dass der zweite Aufruf immer nichts zurückgibt. Sie können das Ergebnis von ReadAll speichern und in Ihren Funktionen wiederverwenden. Zum Beispiel:

bytes, _ := ioutil.ReadAll(r); 
log.Println(string(bytes)) 
1

Technisch können Sie auf einem Leser nicht mehrere Male lesen.

  • Auch wenn Sie verschiedene Referenzen erstellen aber
  • , wenn Sie einmal gelesen wird es gleiches Objekt von allen Referenzen bezeichnet werden.
  • so können Sie den Inhalt lesen und in einer Variablen speichern.
  • Dann verwenden Sie diese Variable so oft wie Sie möchten.

Dies wird zweimal gedruckt.

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

Ich möchte wissen, warum nicht :-) –

+2

@AbhishekSoni: Ein 'io.Reader' ist ein Stream. Sobald du den Stream beendet hast, gibt es keinen mehr. Wenn Sie einen Teil des Streams lesen, wird der nächste Lesevorgang dort fortgesetzt, wo Sie aufgehört haben. – JimB

8

io.Reader ist wie ein Strom behandelt. Aus diesem Grund können Sie es nicht zweimal lesen. Stellen Sie sich eine eingehende TCP-Verbindung vor. Sie können das was nicht zurückspulen kommt in

Aber Sie können die io.TeeReader verwenden, den Strom zu duplizieren.

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

} 

Beispiel auf Go Playground

Verwandte Themen