2011-01-26 25 views
41

संभव डुप्लिकेट:
Do I need to manually close a ifstream?क्या मुझे std :: fstream को बंद करने की आवश्यकता है?

मैं fstream.close() कॉल करने के लिए की जरूरत है या fstream एक उचित आरए II उद्देश्य यह है कि विनाश पर धारा बंद कर देता है है?

मेरे पास एक विधि के अंदर एक स्थानीय std::ofstream ऑब्जेक्ट है। क्या मैं मान सकता हूं कि बंद करने के बिना इस विधि से बाहर निकलने के बाद फ़ाइल हमेशा बंद होती है? मैं विनाशक के दस्तावेज नहीं मिला।

+0

हाँ यह एक डुप्लिकेट है। धन्यवाद। मुझे यह नहीं मिला। –

+3

सटीक डुप्लिकेट नहीं है। संदर्भित प्रश्न ifstreams के लिए विशिष्ट है, और यह आमतौर पर fstreams के बारे में है। –

उत्तर

65

मुझे लगता है कि पिछले उत्तर भ्रामक हैं।

fstream एक उचित आरए II वस्तु है, यह गुंजाइश के अंत में करीब स्वचालित रूप से करता है, और पूरी तरह से जो भी कोई जरूरत नहीं है जब स्कोप के अंत में बंद करने के लिए पर्याप्त है मैन्युअल close कॉल करने के लिए नहीं है।

विशेष रूप से, यह "सर्वोत्तम अभ्यास" नहीं है और आउटपुट को फ्लश करना आवश्यक नहीं है।

और जबकि ड्रकोशा सही है कि close पर कॉल करने से आपको स्ट्रीम के असफल बिट की जांच करने की संभावना मिलती है, वैसे भी कोई भी ऐसा नहीं करता है।

एक आदर्श दुनिया में, कोई भी stream.exception(ios::failbit) को पहले से कॉल करेगा और fstream के विनाशक में फेंक दिया गया अपवाद संभालेंगे। लेकिन दुर्भाग्य से विनाशकों में अपवाद सी ++ में एक टूटी अवधारणा है, इसलिए यह एक अच्छा विचार नहीं है।

तो यदि आप फ़ाइल को बंद करने की सफलता की जांच करना चाहते हैं, तो इसे मैन्युअल रूप से करें (लेकिन केवल तब)।

+4

मैं वास्तव में हर बार नज़दीकी परिणाम की जांच करता हूं, क्योंकि मैं एक एप्लिकेशन पर काम कर रहा हूं जो यह सुनिश्चित करना चाहिए कि डेटा डिस्क पर प्रतिबद्ध है। इसके अलावा, बिंदु से थोड़ी दूर, ** बंद फ्लश ** (कम से कम लिनक्स पर) सुनिश्चित नहीं करता है, और मुझे यकीन नहीं है कि विनाशक फ्लश करता है। मैं वास्तव में कहूंगा कि यह फ्लश और बंद करने के लिए "सर्वोत्तम अभ्यास" है, और दोनों पर इरॉस की जांच करें। – Drakosha

+7

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

+1

मैं उस लिनक्स व्यवहार से थोड़ा आश्चर्यचकित हूं। Fstream destructor को 'क्लोज़' सदस्य फ़ंक्शन को कॉल करने की आवश्यकता होती है, 'बंद करें' को "fclose' द्वारा" बंद करने के लिए आवश्यक है, और 'fclose' को स्ट्रीम को फ़्लश करने के लिए परिभाषित किया गया है। इसलिए विनाशक को निश्चित रूप से फ्लश करना चाहिए, हालांकि मशीन पर प्लग खींचने का जोखिम होने पर फ्लशिंग जरूरी नहीं है कि आप क्या चाहते हैं। इसके लिए आपको (गैर मानक-सी ++) 'fsync' की आवश्यकता है। –

1

मुझे लगता है कि कारण आप बफर फ्लश करने के लिए, कि क्या मैं

+5

अगर fstream एक आरएआईआई वस्तु है, तो यह बंद हो जाएगा और इस प्रकार बफर किसी भी तरह से फ्लश हो जाएंगे। मुख्य सवाल यह है कि मुझे यह सुनिश्चित करने के लिए सभी नियंत्रण प्रवाहों में त्रुटि प्रबंधन की आवश्यकता है कि यह फ़्लश हो। –

+4

क्षमा करें, -1 केवल इसलिए कि यह किसी भी तरह +2 था। संसाधन को मैन्युअल रूप से जारी करना या तो खराब प्रोग्रामिंग का संकेत है, या एक कंटेनर के उद्देश्य की गलतफहमी है। – GManNickG

+0

@GMan: मैं तर्क दूंगा कि आपकी फ़ाइल ठीक से बंद होने पर देखभाल नहीं करना असाधारण मामला है, और आपको अधिकांश स्थितियों में 'बंद()' स्वयं को कॉल करना चाहिए। * सुदूर * बहुत से सॉफ्टवेयर डेवलपर्स धारणाएं करते हैं कि मैं बल्कि उपयोगकर्ता फाइल सिस्टम की विश्वसनीयता और उपलब्धता के बारे में नहीं चाहता था। –

6

बताया गया है एमी ली का जवाब देने के लिए संलग्न करने के लिए की जरूरत है कि यह एक अच्छी आदत है अपने fstream बंद करने के लिए, यह मैन्युअल रूप से ऐसा करने के लिए, क्योंकि इस तरह से बेहतर है आप त्रुटियों की भी जांच कर सकते हैं।

Btw, "close" manpage के अनुसार:

पास की वापसी मूल्य (जाँच नहीं) एक आम लेकिन फिर भी गंभीर प्रोग्रामिंग त्रुटि है। यह काफी संभव है कि पिछले लिखने (2) ऑपरेशन पर त्रुटियों को पहली बार अंतिम बंद() पर रिपोर्ट किया गया है। फ़ाइल को बंद करते समय वापसी मूल्य की जांच नहीं कर सकता डेटा की चुप हानि का कारण बन सकता है। यह विशेष रूप से डिस्क कोटा के साथ एनएफएस और के साथ देखा जा सकता है।

एक सफल करीब गारंटी नहीं है कि डेटा को सफलतापूर्वक किया गया है डिस्क को बचाया, के रूप में गिरी defers लिखता है। फाइल सिस्टम के लिए स्ट्रीम बंद होने पर बफर को फ़्लश करने के लिए यह सामान्य नहीं है। यदि आपको की आवश्यकता है तो सुनिश्चित करें कि डेटा भौतिक रूप से संग्रहीत उपयोग fsync (2) है। (यह इस बिंदु पर डिस्क हार्डवेयर पर पर निर्भर करेगा।)

+1

इसे मैन्युअल रूप से करना बेहतर है * यदि * आपको त्रुटियों की जांच करने की आवश्यकता है, तो इसका मतलब यह नहीं है कि हमें हमेशा * बंद * मैन्युअल रूप से बंद करना चाहिए। आप एक असाधारण मामले से एक सामान्य अभ्यास नहीं कर सकते हैं। सामान्य मामले में, जब यह बंद हो जाता है तो हमें परवाह नहीं है कि यह कैसे सफल हुआ, इसलिए इसे स्वचालित रूप से जाने दें। – GManNickG

+3

@GMan: यदि आप त्रुटियों की जांच नहीं कर रहे हैं, तो इसका मतलब है कि आप अपने उपयोगकर्ता को गुमराह कर रहे हैं कि डेटा डिस्क पर है जबकि यह नहीं है। – Drakosha

+1

@ ड्राकिशा: लेकिन जैसे स्टीव कहते हैं, एक बार जब मैं बंद करता हूं (जो स्वचालित रूप से किया जाता है), त्रुटि या यह मेरे हाथों से बाहर नहीं है। इसके अलावा आपका "संवर्धन" गैर-मानक सी ++ है, हम यहां मानक 'fstream' C++ के बारे में बात कर रहे हैं। – GManNickG

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