I have an io.ReadCloser
object (from an http.Response
object).
What's the most efficient way to convert the entire stream to a string
object?
This question is related to
go
data, _ := ioutil.ReadAll(response.Body)
fmt.Println(string(data))
func copyToString(r io.Reader) (res string, err error) {
var sb strings.Builder
if _, err = io.Copy(&sb, r); err == nil {
res = sb.String()
}
return
}
Answers so far haven't addressed the "entire stream" part of the question. I think the good way to do this is ioutil.ReadAll
. With your io.ReaderCloser
named rc
, I would write,
Go >= v1.16
if b, err := io.ReadAll(rc); err == nil {
return string(b)
} ...
Go <= v1.15
if b, err := ioutil.ReadAll(rc); err == nil {
return string(b)
} ...
The most efficient way would be to always use []byte
instead of string
.
In case you need to print data received from the io.ReadCloser
, the fmt
package can handle []byte
, but it isn't efficient because the fmt
implementation will internally convert []byte
to string
. In order to avoid this conversion, you can implement the fmt.Formatter
interface for a type like type ByteSlice []byte
.
I like the bytes.Buffer struct. I see it has ReadFrom and String methods. I've used it with a []byte but not an io.Reader.
var b bytes.Buffer
b.ReadFrom(r)
// b.String()
Source: Stackoverflow.com