Read Multiple Times from Single io.Reader
In Go, using the io.ReadCloser interface for reading data from a source can present a challenge when attempting to read it multiple times. As an example, consider a scenario where you want to use request.Body (type io.ReadCloser), which contains an image, for both writing directly to a file and decoding.
Problem:
Attempts to create multiple instances of the reader, as in the following code, result in the second call returning a nil value:
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)) }
Solution:
The io.Reader interface models a stream, meaning it cannot be read twice. To overcome this limitation, you can utilize the io.TeeReader function to create a duplicate 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)) }
This code demonstrates how to use io.TeeReader to create a duplicate stream from r and write the content to both tee and buf. By reading from tee first, you can ensure that the buffer is populated with the stream's content.
The above is the detailed content of How Can I Read from an io.Reader Multiple Times in Go?. For more information, please follow other related articles on the PHP Chinese website!