2010-05-10 14 views
9

सी ++ में, std::fwrite() है जो डिस्क पर एक फ़ाइल को बफर लिखता है।क्या fwrite आउटपुट बफर करता है?

क्या आप कृपया मुझे बता सकते हैं कि उस fwrite कार्यान्वयन के अंदर कोई बफर है या नहीं?

यानी यदि मैं कई बार fwrite() को कॉल करता हूं (10 बार कहता हूं), क्या यह वास्तव में फ़ाइल I/O 10 अलग-अलग बार आमंत्रित करता है?

मैं उबंटू 10.04 पर्यावरण के लिए यह पूछ रहा हूं।

उत्तर

10

हां, यह buffered है। बफर का आकार BUFSIZ द्वारा परिभाषित किया गया है। (धन्यवाद @ लडेनेज।) दस पर्याप्त बड़े परिचालनों के परिणामस्वरूप दस सिस्टम कॉल होंगे।

आपको std::setbuf और std::setvbuf का उपयोग करके अपना स्वयं का बफर सेट करने की भी अनुमति है।

cstdio में कार्य सी से विरासत में हैं। सी ++ में पसंदीदा इंटरफ़ेस fstream और filebuf है।

+2

मेरा मानना ​​है कि डिफ़ॉल्ट बफर आकार 'BUFSIZ' है, जैसा कि stdio.h में परिभाषित किया गया है, बेशक कॉलर्स को उस जानकारी की आवश्यकता नहीं होनी चाहिए। कुछ सिस्टम पर आकार को नियंत्रित करने के लिए 'setbuf' का उपयोग किया जा सकता है। – ladenedge

+0

लॉल, आपने सचमुच सटीक दूसरे पर पोस्ट किया है, मैंने एक संपादन किया: "ladenedge 1 sec ago" – Potatoswatter

6

यह निर्भर करता है। अधिकांश प्लेटफ़ॉर्म पर, फ़ाइल IO को कैश किया जाता है इसलिए fflush() डिस्क डिस्क पर कैश किए गए डेटा को लिखने के लिए मौजूद है - उस संबंध में, आपके पहले प्रश्न का उत्तर (आमतौर पर) "हाँ" और आपका दूसरा "नहीं" है। उस ने कहा, किसी भी विशेष मंच के लिए कल्पना के किसी भी हिस्से से इस तरह की गारंटी नहीं है - आम तौर पर, मानक केवल ऐसे कार्यों के लिए इंटरफ़ेस निर्दिष्ट करते हैं, न कि उनके कार्यान्वयन। साथ ही, यह संभव है कि fwrite() पर कॉल करने से कैश "पूर्ण" हो जाए, तो fwrite() पर कॉल करने के मामले में वास्तव में फ़ाइल आईओ को ट्रिगर कर सकता है - खासकर यदि fwrite() को बड़ी मात्रा में डेटा के साथ कॉल करना है।

+1

लाइब्रेरी IO फ़ंक्शंस buffered हैं, लेकिन सिस्टम IO फ़ंक्शन आमतौर पर हैं; इतना ही नहीं, डिस्क नियंत्रक भी एक कैश है। असल में, आमतौर पर डिस्क के साथ समस्या यह सुनिश्चित नहीं कर रही है कि आपका आउटपुट कैश हो जाता है, लेकिन यह सुनिश्चित कर रहा है कि यह * वास्तव में * डिस्क पर लिखा गया हो जब आपको इसकी आवश्यकता हो।:) –

+0

@ मैटेटेओ, मुझे पता है कि आपका क्या मतलब है - उदाहरण के लिए, एक त्रुटि लॉग लिखने के लिए fwrite का उपयोग करना दिलचस्प हो सकता है यदि आपका प्रोग्राम डिस्क पर * कैश लिखे जाने से पहले * क्रैश हो जाता है। सौभाग्य से उस के लिए fflush है ... – Mac

+0

"मानक केवल ऐसे कार्यों के लिए इंटरफेस निर्दिष्ट करते हैं, उनके कार्यान्वयन नहीं" सटीक नहीं है। जबकि मानक कार्यान्वयन निर्दिष्ट नहीं करता है, यह व्यवहार निर्दिष्ट करता है। और इस मामले में, मानक निर्दिष्ट करता है कि FILE * buffered है (C++ 17.3.1.4/1 में सी मानक को शामिल करता है और सी मानक परिभाषित करता है कि फ़ाइल * 7.19.5.6/2 में बफर किया गया है)। –

0

यह पुस्तकालय कार्यान्वयन पर निर्भर करता है। आप dtruss या स्ट्रेस जैसे कुछ सिस्टम कॉल वास्तव में कार्यान्वयन द्वारा लागू किए गए हैं, इस पर कुछ नज़र डालें।

आप इसकी परवाह क्यों करते हैं?

+0

मेरा प्रोग्राम बहुत सारे fwrite() कर रहा है। और यह उबंटू 10.04 पर चल रहा है। मैं जानना चाहता हूं कि प्रदर्शन कारण के लिए fwrite() को कॉल करने से पहले मुझे आईओ को खुद को बफर करना है या नहीं। – michael

+0

@ माइकल: हाँ, I/O बफर करें। 'Fwrite' पर कॉल की संख्या को कम करने से कम से कम आपके कोड में शाखाओं की संख्या कम हो जाएगी। शाखाएं प्रदर्शन को धीमा करती हैं क्योंकि कई प्रोसेसर शाखा के बाद अपने निर्देश कैश को फिर से लोड करते हैं। साथ ही, निष्पादित करने के लिए कम कोड प्रोग्राम को तेज़ी से बनाता है। –

+0

क्यों बाधाओं को खोजने के लिए अपने कोड को प्रोफ़ाइल न करें? – WhirlWind

0

मुझे विश्वास नहीं है कि मानकों के बारे में कुछ भी कहता है लेकिन आम तौर पर: कोई ऑपरेटिंग सिस्टम तय नहीं करेगा कि कितने I/O संचालन करना है। यह 1 हो सकता है यह 10 हो सकता है। डेटा आकार बड़ा होने पर यह और भी अधिक हो सकता है। अधिकांश ऑपरेटिंग सिस्टम आपको यह नियंत्रित करने की अनुमति देते हैं कि I/o को कैसे व्यवहार करना चाहिए लेकिन AFAIK को ऐसा करने का कोई पोर्टेबल तरीका नहीं है। (और अक्सर आप वैसे भी नहीं चाहते हैं)

2

FILE* I/O को buffered किया जा सकता है लेकिन यह होना आवश्यक नहीं है (यह प्रत्येक स्ट्रीम के लिए अलग हो सकता है)। इसके अलावा, बफरिंग करने के कई तरीके हैं (पूरी तरह से बफर किया जाता है जहां बफर को पूर्ण नहीं किया जाता है या fflush पर एक स्पष्ट कॉल किया जाता है या लाइन buffered किया जाता है जहां बफर को ईओएल देखने तक फ़्लश नहीं किया जाता है)। बफरिंग को पूरी तरह से बंद करना भी संभव है।

आप setvbuf कॉल के साथ बफरिंग के प्रकार को बदल सकते हैं।

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