답변:
편집하다:
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.
이 사본은 보호 메커니즘으로 수행됩니다. 문자열은 변경할 수 없습니다. [] 바이트를 문자열로 변환 할 수 있으면 문자열의 내용을 변경할 수 있습니다. 그러나, 안전하지 않은 패키지를 사용하여 유형 안전 메커니즘을 비활성화 할 수 있습니다. 안전하지 않은 패키지는 사용자 책임으로 사용하십시오. 바라건대 이름만으로도 충분히 경고 할 수 있습니다. 안전하지 않은 방법으로 수행하는 방법은 다음과 같습니다.
buf := new(bytes.Buffer)
buf.ReadFrom(yourReader)
b := buf.Bytes()
s := *(*string)(unsafe.Pointer(&b))
이제 바이트 배열을 문자열로 효율적으로 변환했습니다. 실제로이 모든 작업은 형식 시스템이 문자열을 호출하도록 속이는 것입니다. 이 방법에는 몇 가지주의 사항이 있습니다.
내 조언은 공식적인 방법을 고수하는 것입니다. 사본을 만드는 것은 그렇게 비싸지 않으며 안전하지 않은 악의 가치가 없습니다. 문자열이 복사하기에 너무 큰 경우 문자열로 만들면 안됩니다.
strings.Builder
기본 []byte
누수를 방지하고 string
앞으로 지원되는 방식으로 사본없이 변환하여 효율적으로 수행합니다 . 아래의 @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
따라서 두 가지 접근 방식은 거의 동일합니다!
가장 효율적인 방법은 항상 []byte
대신에 사용하는 것입니다 string
.
경우에는로부터 수신 된 데이터를 인쇄 할 필요 io.ReadCloser
는 fmt
패키지가 처리 할 수 []byte
있지만, 때문에 효율적이지 않습니다 fmt
구현이 내부적으로 변환됩니다 []byte
에 string
. 이러한 변환을 피하기 위해 다음 fmt.Formatter
과 같은 유형 의 인터페이스를 구현할 수 있습니다 type ByteSlice []byte
.