2010-07-27 9 views
24

fgetpos/fsetpos और ftell/fseek के बीच क्या अंतर है? fgetpos और fsetpos के लिए क्या अच्छे हैं?fgetpos/fsetpos और ftell/fseek

+0

देखें http://stackoverflow.com/questions/12119132/ftello-fseeko-vs-fgetpos-fsetpos इसका उत्तर यहां स्वीकृत उत्तर से बेहतर तरीका है। – Mecki

उत्तर

17

ठीक है, मैनपेज से हम उस फ़ाइल में ऑफसेट (पदों) का प्रतिनिधित्व करने के लिए ftell और fseek उपयोग प्रकार लंबे int देख सकते हैं, और इसलिए ऑफसेट तक ही सीमित हो सकता है जिसे लंबे int में प्रदर्शित किया जा सकता है। (टाइप करें लंबे int को 2 ** 31-1 से बड़े मान रखने की गारंटी नहीं है, अधिकतम ऑफसेट को 2 गीगाबाइट तक सीमित करना)। दूसरी तरफ, नए fgetpos और fsetpos कार्यों, ऑफसेट का प्रतिनिधित्व करने के लिए एक विशेष typedef, fpos_t का उपयोग करें। इस टाइपपीफ के पीछे का प्रकार, अगर उचित रूप से चुना जाता है, तो मनमाने ढंग से बड़े ऑफसेट का प्रतिनिधित्व कर सकता है, इसलिए fgetpos और fsetpos मनमाने ढंग से बड़ी फ़ाइलों के साथ उपयोग किया जा सकता है। fgetpos और fsetpos भी multibyte धाराओं से जुड़े राज्य रिकॉर्ड।

+5

** यह उत्तर गलत है! ** यदि आप सिर्फ '2 ** 31-1' से अधिक खोजना चाहते हैं तो वहां 'fseeko' है। सही उत्तर यह है कि 'fgetpos' केवल' fgetpos' द्वारा प्राप्त की गई स्थिति की तलाश कर सकता है और 'fpos_t' ** ** को एक पूर्णांक के रूप में नहीं समझा जाना चाहिए, क्योंकि मैन पेज कहता है: * कुछ गैर- यूनिक्स सिस्टम, ** एक fpos_t ऑब्जेक्ट एक जटिल ऑब्जेक्ट ** हो सकता है और ये दिनचर्या एक पाठ स्ट्रीम को पोर्टेबल रूप से स्थानांतरित करने का एकमात्र तरीका हो सकती है। * – Mecki

+0

@Mecki हां वास्तव में, यह उत्तर गलत है। जहां तक ​​मैं समझता हूं कि मेरा उत्तर नीचे एकमात्र सही है। – HughHughTeotl

+1

कोई जवाब गलत नहीं है लेकिन अपर्याप्त है। यह सही ढंग से 'fseek' और दोस्तों की सीमाओं को बताता है, और यह सही ढंग से कहता है कि' fgetpos' और दोस्तों को ऐसी सीमाएं नहीं हैं। ऊपर दिए गए उत्तर में कभी भी कहा गया है कि आप 'fseek' और' fsetpos' और firends को मिश्रण कर सकते हैं, जो वास्तव में खतरनाक है। इसके अलावा, यह कभी नहीं बताता है कि 'fpos_t' एक अभिन्न प्रकार है। इसके बजाय मेकी 'fseeko' और फ़ायरवैंड सुझाता है जो गैर-आईएसओ-सी-मानक फ़ंक्शन (लेकिन POSIX फ़ंक्शन) हैं। – math

-2

कार्यात्मक रूप से कोई अंतर नहीं है, हालांकि इंटरफेस को अलग-अलग परिभाषित किया गया है। वे दोनों लागू किए गए हैं क्योंकि दोनों POSIX का हिस्सा हैं। ऊपर जवाब में से

+2

इन दोनों इंटरफेस आईएसओ सी से हैं, पॉज़िक्स नहीं। और जब फाइलें बहुत बड़ी होती हैं तो गहन कार्यात्मक अंतर होते हैं। – zwol

+0

उनका अंतर वह तरीका है जिस तरह वे स्थिति को संबोधित कर सकते हैं: या तो 'लंबी int' या 'fpos_t' द्वारा। – math

17

कोई भी सही हैं - वास्तव में यदि आप का उपयोग fsetposfseek के लिए भी आप एक सुरक्षा दोष (https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=20087255) शुरू कर सकता है।

कारण यह है कि fpos_t *posfsetpos पर तर्क वास्तव में एक पूर्णांक नहीं है, इसलिए इसका उपयोग किसी फ़ाइल में मनमानी स्थानों की तलाश करने के लिए नहीं किया जा सकता है। इसलिए केवल वैध मान fgetpos से प्राप्त किए गए हैं। डॉक्स के रूप में कहते हैं,

आंतरिक फ़ाइल स्थिति धारा के साथ जुड़े सूचक स्थिति pos का प्रतिनिधित्व करती है, जो एक fpos_t वस्तु जिसका मूल्य पहले से fgetpos के लिए एक कॉल के द्वारा प्राप्त किया गया है जाएगा करने के लिए एक सूचक है पर सेट है।

(http://www.cplusplus.com/reference/cstdio/fsetpos/)

यदि सब आप चाहते हैं 32-बिट सीमा से परे मनमाने ढंग से स्थानों की तलाश है, तो ftello/fseeko का उपयोग करें और #define _FILE_OFFSET_BITS 64 साथ संकलित करने के लिए की क्षमता है।

+0

वास्तव में सवाल के लिए सही जवाब नहीं है, लेकिन टिप के रूप में बहुत अच्छा है! धन्यवाद! – likern

+1

@likern यह सवाल का जवाब है। और यह भी सही उत्तर है, स्वीकृत उत्तर बिल्कुल गलत है, क्योंकि 'fpos_t' बिल्कुल पूर्णांक नहीं हो सकता है (मानक को इसकी आवश्यकता नहीं है)। – Mecki

+0

'ftello' और' fseeko' POSIX फ़ंक्शन हैं। इसके अलावा 7.21.9.1 में सी 11 मानक राज्य :" fgetpos फ़ंक्शन पार्स राज्य (यदि कोई हो) के वर्तमान मानों को संग्रहीत करता है और पॉज़ " द्वारा इंगित ऑब्जेक्ट में स्ट्रीम द्वारा इंगित धारा के लिए फ़ाइल स्थिति संकेतक इसके अलावा: में 7.21.1 यह कहा गया है: "fpos_t' जो एक पूर्ण ऑब्जेक्ट प्रकार है जो एक सरणी प्रकार के अलावा एक फ़ाइल के भीतर विशिष्ट रूप से प्रत्येक स्थिति को निर्दिष्ट करने के लिए आवश्यक सभी सूचनाओं को रिकॉर्ड करने में सक्षम है" हालांकि, कम से कम मेरे सिस्टम पर 'fpos_t' एक '__darwin_off_t' है जो' __int64_t' हो जाता है। possibl जब fsetpos और fgetpos का उपयोग करें – math

3

fgetpos() fsetpos() के साथ चला जाता है। और ftell() fseek() के साथ चला जाता है।

fgetpos() व्यावहारिक रूप से ftell() की तरह दिखता है क्योंकि दोनों एक FILE * पैरामीटर लेते हैं, और दोनों फ़ाइल में किसी प्रकार की स्थिति लौटते हैं, हालांकि थोड़ा अलग शैली के साथ। लेकिन इसे प्राप्त करें: केवल fseek() आपको फाइल की शुरुआत से, फ़ाइल में अपनी वर्तमान स्थिति से, और फ़ाइल के अंत से पीछे की तरफ से खोजने की अनुमति देता है (fseek() को तीसरा तर्क SEEK_SET, SEEK_CUR, और SEEK_END)। fsetpos() यह नहीं करता है। fsetpos() fgetpos() से प्राप्त कुछ स्थिति पर वापस जाने के लिए सीमित है।

हमें बताएं कि आप स्मृति में फ़ाइल को पढ़ना चाहते हैं। Malloc() से आपको कितना ढेर चाहिए? आपको फ़ाइल के आकार की आवश्यकता है। और मुझे अभी तक सी मानक लाइब्रेरी में कोई फ़ंक्शन नहीं मिला है जो आपको फ़ाइल का आकार बताएगा, हालांकि कुछ सी कंपाइलर एक गैर-मानक फ़ंक्शन जोड़ सकते हैं। उदाहरण के लिए, बोर्लैंड टर्बो सी में फाइल लम्बाई() थी। लेकिन मैंने मानक सी लाइब्रेरी के बीच फ़ाइल लम्बाई() नहीं देखा है।

तो, आप फ़ाइल के अंत से पहले fseek() से 0 बाइट्स का उपयोग कर सकते हैं। फिर बाइट्स में स्थिति प्राप्त करने के लिए ftell() का उपयोग करें, और उस पर ढेर मेमोरी की मात्रा के लिए अपनी गणना का आधार लगाएं।

फ़ाइल आकार प्राप्त करने के लिए आप और क्या कर सकते हैं?आप प्रत्येक चरित्र को पढ़ने के लिए fgetc() का उपयोग कर सकते हैं, जब तक आप अंत तक नहीं पहुंच जाते। लेकिन मुझे लगता है कि fseek() और ftell() का उपयोग करना बेहतर और आसान है।

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