2009-06-30 11 views
142

मैं लिखने के तरीकों के लिए एक स्ट्रीम भेज रहा हूं, और उन तरीकों से मैं एक बाइनरी रीडर/wrtier का उपयोग कर रहा हूँ। जब पाठक/लेखक का निपटारा हो जाता है, या तो using या जब इसे संदर्भित नहीं किया जाता है, तो क्या स्ट्रीम भी बंद हो जाती है ??क्या धारावाहिक को स्ट्रीम करने से स्ट्रीम बंद हो जाता है?

मैं एक बाइनरी रीडर/राइटर भेजूंगा, लेकिन मैं स्ट्रीमरिएडर का भी उपयोग कर रहा हूं (शायद मुझे इसके आसपास जाना चाहिए। मैं केवल गेटलाइन और रीडलाइन के लिए इसका उपयोग कर रहा हूं)। जब भी कोई लेखक/पाठक बंद हो जाता है तो यह स्ट्रीम को बंद कर देता है, यह काफी परेशानी है।

उत्तर

166

हाँ, StreamReader, StreamWriter, BinaryReader और BinaryWriter सभी करीब/उनके अंतर्निहित धाराओं निपटाने जब आप उन पर Dispose कहते हैं। वे स्ट्रीम का निपटान नहीं करते हैं यदि पाठक/लेखक सिर्फ कचरा इकट्ठा होता है - आपको हमेशा using कथन के साथ पाठक/लेखक का निपटान करना चाहिए। (वास्तव में, इनमें से किसी भी वर्ग में फाइनलाइज़र नहीं हैं, न ही उनके पास होना चाहिए।)

व्यक्तिगत रूप से मैं स्ट्रीम के लिए भी एक कथन का विवरण देना पसंद करता हूं। आप घोंसला ब्रेसिज़ के बिना काफी बड़े करीने से using बयान कर सकते हैं:

using (Stream stream = ...) 
using (StreamReader reader = new StreamReader(stream, Encoding.Whatever)) 
{ 
} 

हालांकि स्ट्रीम के लिए using बयान कुछ हद तक निरर्थक है (जब तक StreamReader निर्माता एक अपवाद फेंकता है) मैं इसे सबसे अच्छा अभ्यास तो मानते हैं, तो आप से छुटकारा पाने के StreamReader और बस बाद की तारीख में स्ट्रीम का उपयोग करें, आपके पास पहले से ही सही निपटान अर्थशास्त्र होगा।

+2

ओह अच्छा, यह केवल तब होता है जब निपटान बुला, नहीं जब माना जाता है कि अंतिम रूप देने। – Nefzen

+1

@ निफज़न: ऐसा इसलिए है क्योंकि इस बात की कोई गारंटी नहीं है कि आपकी ऑब्जेक्ट्स को किस क्रम में अंतिम रूप दिया जाएगा। यदि StreamReader और अंतर्निहित स्ट्रीम दोनों अंतिम रूप देने के लिए योग्य हैं, तो जीसी पहले स्ट्रीम को अंतिम रूप दे सकता है - फिर स्ट्रीम्रेडर के पास स्ट्रीम का संदर्भ नहीं होगा। इस कारण से, आप केवल अंतिम रूप से अप्रबंधित संसाधनों को रिलीज़ कर सकते हैं (उदाहरण के लिए, एक फ़ाइलस्ट्रीम इसके विंडोज़ फ़ाइल हैंडल को अंतिम रूप में बंद कर देता है)। ओह, और निश्चित रूप से, यदि आप कभी निपटान नहीं करते हैं, तो स्ट्रीम अभी भी एकत्र की जाएगी (और फ़ाइल बंद हो जाएगी)। धारा का निपटान न करने के लिए यह एक बहुत ही बुरी आदत है। – JMarsch

+9

यह घोंसला VS कोड विश्लेषक को शिकायत करने का कारण बनता है: 'CA2202: Microsoft.Usage: ऑब्जेक्ट 'स्ट्रीम' विधि '...' में एक से अधिक बार निपटान किया जा सकता है। एक सिस्टम उत्पन्न करने से बचने के लिए। ऑब्जेक्ट डिस्प्ले अपवाद जिसे आप कॉल नहीं करना चाहिए किसी ऑब्जेक्ट पर एक से अधिक बार निपटाना। 'क्या इसे सिर्फ अनदेखा किया जाना चाहिए? मुझे अब तक कोई अपवाद नहीं मिला है ... –

-3

धारा या तो कीवर्ड "का उपयोग कर" या निपटान के लिए स्पष्ट रूप

27

हाँ, यह करता है को फोन करके निपटाया। आप परावर्तक के साथ कार्यान्वयन को देखकर इसे सत्यापित कर सकते हैं।

protected override void Dispose(bool disposing) 
{ 
    try 
    { 
     if ((this.Closable && disposing) && (this.stream != null)) 
     { 
      this.stream.Close(); 
     } 
    } 
    finally 
    { 
     if (this.Closable && (this.stream != null)) 
     {  
      this.stream = null;  
      this.encoding = null; 
      this.decoder = null; 
      this.byteBuffer = null; 
      this.charBuffer = null; 
      this.charPos = 0; 
      this.charLen = 0; 
      base.Dispose(disposing); 
     } 
    } 
} 
2

हां। कॉलिंग निपटान() पर और IDISposable (जो "उपयोग" करता है) को ऑब्जेक्ट को अपने सभी संसाधनों को साफ करना चाहिए। इसमें धाराओं को फिसलने और बंद करने के लिए उनकी फाइल डिस्क्रिप्टर शामिल हैं।

यदि आपके मामले में, आप इसे अन्य तरीकों से पारित करना चाहते हैं, तो आपको यह सुनिश्चित करना होगा कि वे विधियां एक उपयोग ब्लॉक में अपना पढ़ने/लिखना न करें।

1

स्ट्रीमवाइटर कक्षाओं को ओवरराइड करने के लिए यदि आपको आवश्यकता है तो इसे ठीक करने का एक आसान तरीका विधि का निपटान करें। यहाँ यह कैसे करना है पर कोड के लिए मेरी पोस्ट देखें:

Does .Disposing a StreamWriter close the underlying stream?

31

यह एक पुरानी है, लेकिन मैं आज इसी तरह कुछ करना चाहता था और पाया कि चीजें बदल गई।

public StreamReader(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool leaveOpen) 

केवल समस्या यह है कि यह पूरी तरह से स्पष्ट अन्य पैरामीटर के लिए सेट करने के लिए नहीं है: .net 4.5 के बाद से, वहाँ एक leaveOpen तर्क है।

the msdn page StreamReader निर्माता के लिए से (स्ट्रीम):

यह निर्माता UTF8Encoding को एन्कोडिंग initializes, BaseStream संपत्ति धारा पैरामीटर का उपयोग कर, और करने के लिए आंतरिक बफर आकार यहाँ कुछ मदद है 1024 बाइट्स

कि सिर्फ detectEncodingFromByteOrderMarks जो the source code द्वारा पहचानने छोड़ देता है true

public StreamReader(Stream stream) 
     : this(stream, true) { 
} 

public StreamReader(Stream stream, bool detectEncodingFromByteOrderMarks) 
     : this(stream, Encoding.UTF8, detectEncodingFromByteOrderMarks, DefaultBufferSize) { 
} 

यह अच्छा होगा अगर उन चूक के कुछ उजागर या कर रहे थे तर्क इतना है कि हम सिर्फ लोगों को निर्दिष्ट कर सकते हैं वैकल्पिक थे हम चाहते हैं कि।

+0

बहुत अच्छी जानकारी! इस नए पैरामीटर के बारे में कभी नहीं सुना और यह वास्तव में बहुत समझ में आता है। – julealgon

+0

4.5 में नया जोड़ा नहीं देखा था, धन्यवाद! – TimothyP

8

छह साल देर से लेकिन शायद यह किसी की मदद कर सकता है।

StreamReader डिस्पोजेक्ट होने पर कनेक्शन बंद कर देता है। हालांकि, "StreamReader/StreamWriter के साथ स्ट्रीम (स्ट्रीम स्ट्रीम = ...) {...} का उपयोग करके स्ट्रीम को दो बार निपटाया जा सकता है: (1) जब StreamReader ऑब्जेक्ट का निपटारा किया जाता है (2) और जब ब्लॉक का उपयोग कर स्ट्रीम बंद कर देता है। वीएस के कोड विश्लेषण को चलाने के दौरान इसका परिणाम CA2202 चेतावनी में होता है।

CA2202 पृष्ठ से सीधे लिया गया एक और समाधान, कोशिश/आखिरकार ब्लॉक का उपयोग करना है। सही तरीके से सेटअप करें, यह केवल एक बार कनेक्शन बंद कर देगा।

CA2202 के निचले भाग के पास, माइक्रोसॉफ्ट निम्नलिखित का उपयोग करने की सिफारिश की:

Stream stream = null; 
try 
{ 
    stream = new FileStream("file.txt", FileMode.OpenOrCreate); 
    using (StreamWriter writer = new StreamWriter(stream)) 
    { 
     stream = null; 
     // Use the writer object... 
    } 
} 
finally 
{ 
    if(stream != null) 
     stream.Dispose(); 
} 
बजाय

...

// Generates a CA2202 warning 
using (Stream stream = new FileStream("file.txt", FileMode.Open)) 
using (XmlReader reader = new XmlReader (stream)) 
{ 
    // Use the reader object... 
} 
+2

हां यह मेरे लिए बहुत उपयोगी था, अब 7 साल बाद :) – Sebastian

+0

स्वीकार्य उत्तर की टिप्पणियों में भी चेतावनी पर चर्चा की गई है। जॉन स्कीट वहां कुछ सलाह प्रदान करता है। – Marcin

संबंधित मुद्दे