回答:
編集:
1.10以降、strings.Builderが存在します。例:
buf := new(strings.Builder)
n, err := io.Copy(buf, r)
// check errors
fmt.Println(buf.String())
以下の古い情報
簡単に言えば、文字列に変換するにはバイト配列の完全なコピーを行う必要があるため、効率的ではありません。ここにあなたが望むことをするための適切な(非効率的な)方法があります:
buf := new(bytes.Buffer)
buf.ReadFrom(yourReader)
s := buf.String() // Does a complete copy of the bytes in the buffer.
このコピーは保護メカニズムとして行われます。文字列は不変です。[]バイトを文字列に変換できれば、文字列の内容を変更できます。ただし、goでは、安全でないパッケージを使用してタイプセーフメカニズムを無効にすることができます。安全でないパッケージは自己責任で使用してください。うまくいけば、名前だけで十分な警告になります。これが私が安全でないことを使ってそれを行う方法です:
buf := new(bytes.Buffer)
buf.ReadFrom(yourReader)
b := buf.Bytes()
s := *(*string)(unsafe.Pointer(&b))
これで、バイト配列を文字列に効率的に変換できました。本当に、これはすべて、型システムをだまして文字列と呼ぶことです。この方法にはいくつかの注意点があります。
私のアドバイスは公式の方法に固執することです。コピーを行うことはないという高価な、それは危険なの悪価値がありません。文字列が大きすぎてコピーできない場合は、文字列にしないでください。
strings.Builder
基になる[]byte
リークが発生しないことを保証し、string
今後サポートされる方法でコピーなしに変換することにより、これを効率的に実行します。これは2012年には存在しませんでした。以下の@dimchanskyのソリューションは、Go 1.10以降の正しいソリューションです。編集をご検討ください!
これまでのところ、質問の「ストリーム全体」の部分は回答されていません。これを行うには良い方法だと思いますioutil.ReadAll
。あなたのio.ReaderCloser
名前を使ってrc
、私は書くでしょう、
if b, err := ioutil.ReadAll(rc); err == nil {
return string(b)
} ...
buf.ReadFrom()
EOFまでのストリーム全体を読み取るようにも見えます。
ioutil.ReadAll()
、それは単にラップbytes.Buffer
さんをReadFrom
。そして、バッファのString()
メソッドはキャストする単純なラップアラウンドですstring
–したがって、2つのアプローチは実質的に同じです!
最も効率的な方法は、の[]byte
代わりに常にを使用することですstring
。
から受信したデータを印刷する必要がある場合 io.ReadCloser
、fmt
パッケージが処理することができ[]byte
ますが、ので、それは効率的ではないfmt
実装が内部的に変換されます[]byte
しstring
。この変換を回避するためにfmt.Formatter
、のようなタイプのインターフェースを実装できますtype ByteSlice []byte
。
var b bytes.Buffer
b.ReadFrom(r)
// b.String()
私はbytes.Buffer構造体が好きです。私はそれが持って見ReadFromと文字列のメソッドを。[]バイトで使用しましたが、io.Readerでは使用していません。