2012-05-28 13 views
9

CreateFile बनाम fopen बनाम ofsteam - लाभ & हानि?CreateFile बनाम fopen बनामस्टीम लाभ और नुकसान?

मैंने सुना है कि CreateFile शक्तिशाली लेकिन केवल विंडोज़ के लिए।
क्या आप बता सकते हैं कि मुझे (विंडोज़ पर) क्या उपयोग करना चाहिए और क्यों?

उत्तर

7

यह आपके द्वारा किए जा रहे कार्यों पर निर्भर करता है। अनुक्रमिक रूप से पाठ फ़ाइलों को पढ़ने और लिखने के लिए, Iostream निश्चित रूप से जाने का तरीका है। लेनदेन संबंधी सुरक्षा या गैर मानक उपकरणों से जुड़े किसी भी चीज़ के लिए, आपको सीधे सिस्टम (CreateFile या open) तक पहुंच प्राप्त करनी होगी। फिर भी, अनुक्रमिक पढ़ने और पाठ के लेखन के लिए, सबसे अच्छा समाधान अपने streambuf को परिभाषित करना है, और iostream के साथ इसका उपयोग करना है।

मैं किसी भी संदर्भ के बारे में नहीं सोच सकता जहां fopen बेहतर होगा।

+0

मुझे शक्ति चाहिए :) लिखना और बाइनरी पढ़ें। केवल विंडोज सिस्टम के लिए। जैसा कि मैंने खुला सुना और fopen createfile से मेल नहीं खाता? यह सच है? – Eveler

+1

@Eveler: यदि आप पूर्ण शक्ति चाहते हैं, तो फ़ाइल को संसाधित करने के लिए आप सबसे तेज़ चीज इसे 'CreateFile' के साथ खोलना है और इसे 'CreateFileMapping'' के साथ मेमोरी में मैप करना है, जैसा कि [इस ब्लॉग पोस्ट] में दिखाया गया है (http: //blogs.msdn.com/b/oldnewthing/archive/2005/05/13/417183.aspx), जो ऑप्टिमाइज़ेशन श्रृंखला का हिस्सा है जो [मानक C++] से शुरू होता है (http://blogs.msdn.com/ बी/oldnewthing/संग्रह/2005/05/10/415991.aspx) और फिर प्रगतिशील रूप से [Win32 अनुकूलित कोड] पर चला जाता है (http://blogs.msdn.com/b/oldnewthing/archive/2005/05/19/420038 .aspx)। लेकिन ज्यादातर मामलों में सरल मानक सी और सी ++ ठीक हैं। –

+3

'fopen' एक उच्च स्तरीय फ़ंक्शन है, जिसे C++ में' fstream :: open' द्वारा प्रतिस्थापित किया गया है। 'CreateFile' और' open' सिस्टम स्तर के फ़ंक्शन हैं, विंडोज़ में पहला, यूनिक्स में दूसरा। वे बिल्कुल वही चीज़ नहीं देते हैं, क्योंकि सिस्टम विभिन्न सुविधाओं का अलग-अलग समर्थन करते हैं। –

1

ज्यादातर मामलों में आप सी ++ में सी या ऑफस्ट्रीम में फॉपेन का उपयोग करने के बेहतर होंगे। CreateFile साझा करने और कैशिंग पर कुछ अतिरिक्त नियंत्रण देता है लेकिन प्रारूपण कार्यक्षमता प्रदान नहीं करता है।

+1

तो आप एक 'स्ट्रीमबफ' लिखते हैं जो 'CreateFile' का उपयोग करने के तरीके की तरह आपको उपयोग करता है, और दोनों के फायदे प्राप्त करता है। –

+0

मैं हमेशा सोच रहा था, IOstreams में एक नए स्रोत या गंतव्य में प्लग करने के लिए इतना बोझिल क्यों है। यदि कुछ भी हो, तो सी ++ डेटा लेखक/पाठक के लिए एक शुद्ध अमूर्त वर्ग घोषित करना आसान बनाता है ... –

4

जब तक आप Windows फ़ाइल कार्यों के द्वारा उपलब्ध कराई गई सुविधाओं की जरूरत है (उदाहरण के लिए मैं ओवरलैप/ओ) तो मेरे सुझाव अधिक पोर्टेबल होने के अलावा सी में या तो iostreams ++ या FILE (fopen और दोस्तों) सी

में साथ जा रहा है , आप टेक्स्ट फ़ाइलों के लिए फॉर्मेटेड इनपुट/आउटपुट का भी उपयोग कर सकते हैं, और सी ++ के लिए अपने वर्गों के लिए आउटपुट/इनपुट ऑपरेटर को अधिभार करना आसान है।

+2

'std :: streambuf' से प्राप्त करना और कुछ "विशेष" विशेषताओं (लेनदेन संबंधी अखंडता, विशेष डिवाइस) से प्राप्त करना भी आसान है। , आदि।)। –

2

जब तक आप absoulutely ओएस एपीआई कार्यों द्वारा प्रदान की अतिरिक्त कार्यक्षमता की जरूरत है (जैसे CreateFile) मैं मानक पुस्तकालय कार्यों (जैसे fopen या ofstream) का उपयोग कर की सिफारिश चाहते हैं। इस तरह आपका कार्यक्रम अधिक पोर्टेबल होगा।

CreateFile का उपयोग करने का केवल वास्तविक लाभ यह है कि मैं के ओवरलैप हो रही है मैं/हे और शायद बेहतर सुक्ष्म अधिकारों का उपयोग सोच सकते हैं।

+2

Createfile 260 से अधिक लंबाई तक फ़ाइल पथ खोल सकता है। – Eveler

+0

पर्याप्त मेला! +1 – cyco130

2

आप Windows फ़ाइल स्मृति मानचित्रण का उपयोग करने के आप CreateFile का उपयोग करना चाहिए (उदाहरण के लिए HANDLECreateFileMapping एपीआई के लिए पारित CreateFile की वापसी मान है) चाहते हैं। इसके अलावा, CreateFile सी और सी ++ मानक फ़ाइल एपीआई से उच्च अनुकूलन विकल्प प्रदान करता है।

हालांकि, अगर आप पोर्टेबल कोड लिखना चाहते हैं, या यदि आपको विंडोज-विशिष्ट विशेषताओं की आवश्यकता नहीं है, तो सी और सी ++ मानक फ़ाइल एपीआई ठीक हैं। कुछ परीक्षणों में, बड़े डेटा को संसाधित करते समय, मैंने सी ++ I/O धाराओं बनाम कच्चे सी फ़ाइल एपीआई के कुछ प्रदर्शन ओवरहेड को नोट किया; यदि आप इस तरह के मामलों में होते हैं, तो आप कुछ सी ++ आरएआईआई कक्षा में कच्चे सी फ़ाइल एपीआई को आसानी से लपेट सकते हैं, और फिर भी इसे सी ++ कोड में उपयोग कर सकते हैं।

+0

मुझे 4 जीबी से 10 जीबी तक बड़ी डेटा फाइलों की आवश्यकता है और मेम मैपिंग मैं भी इसका उपयोग करूंगा। – Eveler

+0

इसलिए यदि आपको मेमोरी मैपिंग की आवश्यकता है तो आप सीधे Win32 API कॉल का उपयोग कर सकते हैं और उन्हें C++ RAII कक्षाओं में लपेट सकते हैं। –

0

मैं

fopen or CreateFile in Windows

जो किसी कारण जो मुझे निकल जाता है के लिए बंद हो गया से मेरा उत्तर की नकल की ...

  1. fopen() वापस जाने के लिए प्रणाली त्रुटि के लिए कोई परिभाषित तरीका नहीं है कोड।इरनो तक पहुंचने के लिए एक अनिर्धारित तरीका हो सकता है, लेकिन यह सिस्टम त्रुटि कोड के समान हो सकता है या नहीं।
  2. इसके अलावा, मुझे नहीं लगता कि वास्तविक सिस्टम हैंडल (प्रकार हैंडल) तक पहुंचने का एक परिभाषित तरीका है, जिसके बदले में आप कई Win64 सिस्टम कॉलों में से किसी एक को पास करने के लिए उपयोग करना चाहेंगे जो इस तरह की उम्मीद करता है सिस्टम हैंडल (उदाहरण के लिए मेमोरी मैप किए गए आईओ)
  3. खुले() एक पूर्णांक का उपयोग फ़ाइल हैंडल का प्रतिनिधित्व करता है, जो सिस्टम हैंडल (विंडोज़ पर) नहीं है।
  4. fopen() त्रुटि के मामले में अपवाद नहीं फेंकता है। कुछ आरएआईआई रखने के लिए आपको इसे कक्षा में लपेटने की आवश्यकता होगी।
  5. एक वर्ग में CreateFile() लपेटना, एक वर्ग में fopen() या open() लपेटने से अधिक महंगा नहीं है।
  6. लिखने के लिए/पढ़ने के लिए/फाइलों से रूप में एक ही समस्या से ग्रस्त है सी ++ सुविधा (std :: ofstream, std :: ifstream) का उपयोग करना fopen():
    • यह त्रुटि पर डिफ़ॉल्ट रूप से फेंक नहीं है। इस सुविधा को सक्षम करने के लिए आपको कुछ कन्स्ट्रक्टर तर्क का उपयोग करने में सक्षम होने के बजाय कुछ विधि कॉल करने की आवश्यकता है - आरएआईआई के लिए आपको इस वर्ग को प्राप्त करने की आवश्यकता होगी (इसे सदस्य/आधार वर्ग के रूप में उपयोग करने के लिए जो त्रुटि पर फेंकता है) ।
    • यह अपरिभाषित है अगर कोई अपवाद से सिस्टम त्रुटि कोड पुनर्प्राप्त करने में सक्षम है या यदि संदेश से वापस लौटाया गया संदेश() आपको सिस्टम त्रुटि के बारे में कुछ बताता है।
    • इस स्ट्रीम इंटरफ़ेस का उपयोग करने से पढ़ने या लिखने के स्रोत या गंतव्य को परिभाषित करने के लिए कोई वास्तविक प्लग करने योग्य इंटरफ़ेस नहीं है। स्ट्रीम इंटरफ़ेस को ओवरलोड करना काफी बोझिल और त्रुटि प्रवण है।
  7. प्रोग्रामिंग (पर ध्यान देने या वापसी कोड अनदेखी और मैन्युअल रूप से सफाई कोड लिखने) की तरह सी का उपयोग करना बहुत बुराई का स्रोत है (याद दिल खून बहाना?) ...

निष्कर्ष:

  1. CreateFile()/CloseHandle() के लिए संसाधन रैपर लिखें। संसाधन रैपर एक वर्ग है, जो कन्स्ट्रक्टर में डू-एक्शन करता है और विनाशक में पूर्ववत करता है और त्रुटि के मामले में अपवाद फेंकता है। प्रत्येक ओएस में सिस्टम कॉल के ऐसे कई जोड़े हैं, खासकर Win64 में।
  2. एक सिस्टम त्रुटि अपवाद वर्ग लिखें (CreateFile() विफल होने और अन्य सभी सिस्टम त्रुटियों के लिए उपरोक्त वर्ग के लिए उपयोग करने के लिए) या जांच करें, नया system_exception वर्ग (C++ 0x में) वास्तव में क्या कर रहा है और यदि यह पर्याप्त है।
  3. ReadFile() और WriteFile() जो एक प्रणाली अपवाद उत्पन्न वस्तु में एक प्रणाली त्रुटि धर्मान्तरित के लिए एक कार्यात्मक आवरण लिखना ...
  4. संभावित करने के लिए कहीं न कहीं लिख सकते हैं और इतना है कि आप लागू कर सकते हैं कहीं से पढ़ने के लिए अपने स्वयं के इंटरफेस को परिभाषित स्रोत/गंतव्य के प्रकार से पढ़ने/लिखने के लिए स्वतंत्र अन्य चीजें।
  5. एक कैश क्लास लिखना जो आपको कहीं से पढ़ने या कहीं भी लिखने की अनुमति देता है, वह भी बच्चे का खेल है। बेशक कैश क्लास को उस स्रोत/गंतव्य के बारे में पता नहीं होना चाहिए और न ही उस पर ध्यान देना चाहिए जिसे आप लिख रहे हैं/पढ़ रहे हैं।

इन छोटे कार्यों के बारे में डरो मत। आपको वास्तव में पता चलेगा कि आपके कोड में क्या हो रहा है और कोड के इन छोटे टुकड़े कोड को कॉल करने की तुलना में नगण्य (कोड की रेखाओं की मात्रा में) होना चाहिए। इसके अलावा यदि आप सब कुछ के लिए आरएआईआई का उपयोग कर रहे हैं, तो इन यूटिलिटी क्लासेस में कॉल करने वाले कोड, आरएआईआई का उपयोग न करने की तुलना में काफी कम होंगे और दो या दो से अधिक चरण प्रारंभिक और काफी कम त्रुटि प्रवण का उपयोग करना होगा।अन्य ओएस के लिए समतुल्य उपयोगिता कक्षाओं के साथ इन उपयोगिता वर्गों को प्रतिस्थापित करना भी बाल खेल है (यूनिक्स पर खुला()/बंद()/पढ़ना()/लिखना() का उपयोग करना)।

और पिछले सहस्राब्दी के लिए Google प्रोग्रामिंग दिशानिर्देशों को नहीं पढ़ा है!

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