2009-03-02 6 views

उत्तर

2

एक StringWriter के लिए एक फ़ाइल स्मृति पाठ लिखने के लिए प्रयोग किया जाता है और एक StringBuilder तार एक स्मृति-कुशल तरीके से एक साथ संलग्न करने के लिए प्रयोग किया जाता है।

0

StringBuilder बड़े पैमाने पर स्ट्रिंगेशन के लिए उपयोग किया जाता है। यह 5 स्ट्रिंग के लिए अधिक प्रभावी है, जहां तक ​​मुझे पता है, तो String.Concat()। इसके अलावा यह विशिष्ट प्रारूप (.AppendFormat())

+0

आपका अंतिम अनुच्छेद स्ट्रिंग * बिल्डर * पर लागू होता है, स्ट्रिंगवाइटर नहीं। –

+1

हम्म .. एमएसडीएन ने कहा कि "स्ट्रिंगवाइटर क्लास एक स्ट्रिंग को जानकारी लिखने के लिए टेक्स्टवाइटर लागू करता है" http://msdn.microsoft.com/en-us/library/system.io.stringwriter.aspx – abatishchev

3

StringBuilder वर्ग मूल रूप से एक परिवर्तनशील स्ट्रिंग, निर्माण अपरिवर्तनीय स्ट्रिंग के लिए एक सहायक वर्ग है के साथ प्रयोग किया जा सकता है। स्ट्रिंग स्वरूपण के लिए अधिक सुविधा कार्यों को जोड़ने के लिए StringWriter शीर्ष पर बनाया गया है।

54

StringWriterTextWriter से निकला, जो विभिन्न वर्गों को यह कहने के बिना पाठ लिखने की अनुमति देता है कि यह कहां जा रहा है। StringWriter के मामले में, आउटपुट सिर्फ स्मृति में है। यदि आप एक एपीआई कॉल कर रहे हैं, तो आप इसका उपयोग करेंगे, जिसे TextWriter की आवश्यकता है, लेकिन आप केवल स्मृति में परिणाम बनाना चाहते हैं।

StringBuilder अनिवार्य रूप से एक बफर है जो आपको प्रत्येक बार एक नई स्ट्रिंग ऑब्जेक्ट के बिना "लॉजिकल स्ट्रिंग" में एकाधिक संचालन (आमतौर पर संलग्न) करने की अनुमति देता है। आप इसे कई संचालन में एक स्ट्रिंग बनाने के लिए उपयोग करेंगे।

69

मुझे नहीं लगता कि मौजूदा उत्तरों में से कोई भी वास्तव में प्रश्न का उत्तर देता है। दो वर्गों के बीच वास्तविक संबंध the adaptor pattern का एक उदाहरण है।

StringWriterStringBuilder के उदाहरण पर अग्रेषित करके Write... विधियों को लागू करता है जो इसे किसी फ़ील्ड में संग्रहीत करता है। यह केवल एक आंतरिक विवरण नहीं है, क्योंकि StringWriter में सार्वजनिक विधि GetStringBuilder है जो आंतरिक स्ट्रिंग बिल्डर देता है, और a constructor जो आपको मौजूदा StringBuilder में पास करने की अनुमति देता है।

तो StringWriter एक एडाप्टर है जो StringBuilder को कोड द्वारा लक्षित लक्ष्य के रूप में उपयोग करने की अनुमति देता है जो TextWriter के साथ काम करने की अपेक्षा करता है। बुनियादी व्यवहार के संदर्भ में उनके बीच चयन करने के लिए स्पष्ट रूप से कुछ भी नहीं है ... जब तक आप कॉल अग्रेषित करने के ऊपरी हिस्से को माप नहीं सकते हैं, इस मामले में StringWriter थोड़ा धीमा है, लेकिन ऐसा लगता है कि यह महत्वपूर्ण होने की संभावना नहीं है।

तो उन्होंने StringBuilder को TextWriter लागू क्यों नहीं किया? यह एक भूरा क्षेत्र है, क्योंकि एक इंटरफेस के पीछे इरादा हमेशा पहली नज़र में स्पष्ट नहीं है।

TextWriterबहुत करीब वर्णों की धारा स्वीकार करने वाले किसी इंटरफ़ेस के लिए एक इंटरफ़ेस है। लेकिन इसमें एक अतिरिक्त शिकन है: Encoding नामक एक संपत्ति। इसका तात्पर्य है कि TextWriter कुछ ऐसा इंटरफ़ेस है जो अक्षरों की धारा स्वीकार करता है और उन्हें बाइट में परिवर्तित करता है।

यह StringWriter में एक बेकार बेस्टिज है क्योंकि यह कोई एन्कोडिंग नहीं करता है।documentation का कहना है:

यह गुण कुछ एक्सएमएल परिदृश्यों जहां एक हैडर StringWriter द्वारा प्रयुक्त एन्कोडिंग युक्त लिखा होना चाहिए के लिए आवश्यक है। यह XML कोड को मनमाने ढंग से स्ट्रिंगवाइटर का उपभोग करने की अनुमति देता है और सही XML शीर्षलेख उत्पन्न करता है।

लेकिन यह सही नहीं हो सकता है, हमें StringWriter के लिए Encoding का मूल्य निर्दिष्ट करने के लिए के लिए कोई रास्ता नहीं है क्योंकि वहाँ। संपत्ति का मूल्य हमेशा UnicodeEncoding है। नतीजतन कोई भी कोड जिसने इस प्रॉपर्टी की जांच एक्सएमएल हेडर बनाने के लिए की थी, हमेशा utf-16 कहती है। उदाहरण के लिए:

var stringWriter = new StringWriter(); 
using (var xmlWriter = XmlWriter.Create(stringWriter)) 
    xDocument.WriteTo(xmlWriter); 

कि शीर्ष लेख का उत्पादन:

<?xml version="1.0" encoding="utf-16"?> 

क्या होगा यदि आप File.WriteAllText इस्तेमाल किया एक फाइल करने के लिए अपने XML स्ट्रिंग लिखने के लिए? डिफ़ॉल्ट रूप से, आपके पास utf-16 शीर्षलेख वाला utf-8 फ़ाइल होगी।

ऐसी परिस्थिति में यह StreamWriter उपयोग करने के लिए सुरक्षित हो जाएगा, और एक फ़ाइल पथ, या एक FileStream के साथ निर्माण, या यदि आप डेटा का परीक्षण करना तो एक MemoryStream और इतने obtain an array of bytes का उपयोग करें। इन सभी संयोजनों से यह सुनिश्चित होगा कि बाइट्स और हेडर पीढ़ी के लिए एन्कोडिंग को आपके StreamWriter में उसी Encoding मान द्वारा निर्देशित किया जा रहा था।

Encoding संपत्ति का उद्देश्य चरित्र धाराओं के जनरेटर को चरित्र स्ट्रीम में एन्कोडिंग के बारे में सटीक जानकारी शामिल करने की अनुमति देना था (जैसे कि XML उदाहरण में; अन्य उदाहरणों में ईमेल शीर्षलेख शामिल हैं) और इसी तरह)।

लेकिन StringWriter पेश करके, सामग्री उत्पादन और एन्कोडिंग के बीच यह लिंक टूटा हुआ है, और इसलिए ऐसे स्वचालित तंत्र काम करना बंद कर देते हैं और संभावित रूप से त्रुटि प्रवण हो जाते हैं।

फिर भी, StringWriter एक उपयोगी एडाप्टर है यदि आप सावधान हैं, यानी आप समझते हैं कि आपकी सामग्री पीढ़ी कोड Encoding संपत्ति के अर्थहीन मूल्य पर निर्भर नहीं होना चाहिए। लेकिन उस तरह की चेतावनी आमतौर पर एडाप्टर पैटर्न से जुड़ी होती है। यह अक्सर एक प्रकार का हैक है जो आपको एक चौकोर छेद में स्क्वायर-आइश-लेकिन-लगभग गोल पेग फिट करने की अनुमति देता है।

+0

@ सैंडरॉक दूसरे पैराग्राफ –

3

पिछले (अच्छे) उत्तरों पर बिल्डिंग, स्ट्रिंगवाइटर वास्तव में स्ट्रिंगबिल्डर से अधिक बहुमुखी है, जो बहुत सारे अधिभार प्रदान करता है।

उदाहरण के लिए

:

जबकि stringbuilder केवल Appendline

के लिए एक स्ट्रिंग या कुछ भी नहीं
StringBuilder sb = new StringBuilder(); 
sb.AppendLine("A string"); 

StringWriter एक स्ट्रिंग प्रारूप सीधे

StringWriter sw = new StringWriter(); 
sw.WriteLine("A formatted string {0}", DateTime.Now); 

StringBuilder के साथ एक ऐसा करने चाहिए ले जा सकते हैं स्वीकार (या स्ट्रिंग का प्रयोग करें।स्वरूप, या $ "")

sb.AppendFormat("A formatted string {0}", DateTime.Now); 
sb.AppendLine(); 

नहीं है या सामान मर जाते हैं, लेकिन अभी भी एक अंतर

1

StringBuilder और StringReader विभिन्न स्थितियों में प्रदर्शन में सुधार करने के लिए इस्तेमाल कर रहे हैं।
StringBuilder स्ट्रिंग मैनिपुलेशन जैसे प्रदर्शन को बेहतर बनाने के लिए, बार-बार स्ट्रिंग को संशोधित करने के लिए उपयोग करें।

Random rnd = new Random(); 
StringBuilder sb = new StringBuilder(); 

// Generate 10 random numbers and store in sb. 
for (int i = 0; i < 10; i++) 
{ 
    sb.Append(rnd.Next().ToString("N5")); 
} 
Console.WriteLine("The original string:"); 
Console.WriteLine(sb.ToString()); 

// Decrease each number by one. 
for (int ctr = 0; ctr < sb.Length; ctr++) 
{ 
    if (Char.GetUnicodeCategory(sb[ctr]) == System.Globalization.UnicodeCategory.DecimalDigitNumber) 
    { 
     int number = (int)Char.GetNumericValue(sb[ctr]); 
     number--; 
     if (number < 0) 
      number = 9; 

     sb[ctr] = number.ToString()[0]; 
    } 
} 
Console.WriteLine("\nThe new string:"); 
Console.WriteLine(sb.ToString()); 

उपयोगStringReader अलग पंक्तियों में टेक्स्ट की एक बड़ी राशि को पार्स और डेटा को संसाधित करते समय स्मृति उपयोग को कम करने। अगला उदाहरण देखें जहां स्ट्रिंग रीडर पर रीडलाइन विधि वर्तमान पोस्टियन से शुरू होने वाली अगली न्यूलाइन के लिए स्कैन करती है, और उसके बाद फ़ील्ड स्ट्रिंग के आधार पर एक एसबीस्ट्रिंग लौटाती है।

using (StringReader sr = new StringReader("input.txt")) 
{ 
    // Loop over the lines in the string or txt file. 
    int count = 0; 
    string line; 
    while((line = sr.ReadLine()) != null) 
    { 
     count++; 
     Console.WriteLine("Line {0}: {1}", count, line); 
    } 
} 
+0

देखें कृपया डाउनवॉटिंग के लिए स्पष्टीकरण प्रदान करें ... –

+0

अच्छा जवाब .... – Unbreakable