जवाबों:
संपादित करें:
1.10 के बाद से, तार। उदाहरण:
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
एक प्रतिलिपि के बिना परिवर्तित करने का समर्थन करता है जो आगे जाकर समर्थित होगा। यह 2012 में मौजूद नहीं था। @ 1.10 के बाद से डाइमेन्स्की का घोल सही हो गया है। कृपया एक संपादन पर विचार करें!
अब तक के उत्तर प्रश्न के "संपूर्ण स्ट्रीम" भाग को संबोधित नहीं करते हैं। मुझे लगता है कि ऐसा करने का अच्छा तरीका है ioutil.ReadAll
। आपके io.ReaderCloser
नाम के साथ rc
, मैं लिखूंगा,
if b, err := ioutil.ReadAll(rc); err == nil {
return string(b)
} ...
buf.ReadFrom()
ईओएफ तक पूरी धारा को भी पढ़ता है।
ioutil.ReadAll()
और यह बस एक लपेटता bytes.Buffer
है ReadFrom
। और बफ़र की String()
विधि कास्टिंग के आसपास एक सरल आवरण है string
- इसलिए दोनों दृष्टिकोण व्यावहारिक रूप से समान हैं!
data, _ := ioutil.ReadAll(response.Body)
fmt.Println(string(data))
सबसे कुशल तरीका हमेशा के []byte
बजाय उपयोग करना होगाstring
।
यदि आपको डेटा प्राप्त करने की आवश्यकता होती है io.ReadCloser
, तो fmt
पैकेज संभाल सकता है []byte
, लेकिन यह कुशल नहीं है क्योंकि fmt
कार्यान्वयन आंतरिक रूप से परिवर्तित []byte
हो जाएगा string
। इस रूपांतरण से बचने के लिए, आप fmt.Formatter
इंटरफ़ेस को एक प्रकार के लिए लागू कर सकते हैं type ByteSlice []byte
।
[]byte
करने के लिए string
यथोचित तेजी से है, लेकिन सवाल "सबसे कारगर तरीका" के बारे में पूछ रहा था। वर्तमान में, जाओ रन-टाइम हमेशा एक नया आवंटित करेगा string
जब परिवर्तित []byte
करने के लिए string
। इसका कारण यह है कि संकलक को यह निर्धारित करने का तरीका नहीं पता है कि []byte
रूपांतरण के बाद इसे संशोधित किया जाएगा या नहीं । संकलक अनुकूलन के लिए यहाँ कुछ जगह है।
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
}
var b bytes.Buffer
b.ReadFrom(r)
// b.String()