जवाबों:
एक फाइल डिस्क्रिप्टर एक निम्न-स्तरीय पूर्णांक "हैंडल" है, जिसका उपयोग लिनक्स या अन्य यूनिक्स जैसी प्रणालियों में, कर्नेल स्तर पर एक खुली हुई फ़ाइल (या सॉकेट, या जो कुछ भी) की पहचान करने के लिए किया जाता है।
आप इस तरह के रूप में वास्तविक यूनिक्स कॉल, करने के लिए "नग्न" फ़ाइल वर्णनकर्ता पारित read()
, write()
और इतने पर।
एक FILE
सूचक एक सी मानक पुस्तकालय स्तर के निर्माण, एक फ़ाइल का प्रतिनिधित्व करते थे है। FILE
फ़ाइल वर्णनकर्ता लपेटता है, और बफरिंग और अन्य सुविधाओं कहते हैं मैं / हे आसान बनाने के लिए।
उत्तीर्ण होने FILE
जैसे मानक सी कार्यों के लिए संकेत दिए गए fread()
और fwrite()
।
fd
यह पहला तर्क है read()
। आप इसे नग्न क्यों कहते हैं?
FILE *
प्रकार की तुलना में , पूर्णांक फ़ाइल डिस्क्रिप्टर "कम लिपटे", अर्थात "नग्न" है।
एक बफर ( FILE *
) है और दूसरा नहीं है। व्यवहार में, आप FILE *
लगभग हमेशा उपयोग करना चाहते हैं जब आप एक 'वास्तविक' फ़ाइल (यानी ड्राइव पर) से पढ़ रहे हैं, जब तक कि आप नहीं जानते कि आप क्या कर रहे हैं या जब तक कि आपकी फ़ाइल वास्तव में सॉकेट या ऐसा नहीं है ..
आप फ़ाइल डिस्क्रिप्टर का FILE *
उपयोग करके प्राप्त कर सकते हैं fileno()
और आप FILE *
एक फ़ाइल डिस्क्रिप्टर का उपयोग करके बफ़र खोल सकते हैंfdopen()
एक फाइल डिस्क्रिप्टर सिर्फ एक पूर्णांक है जो आपको POSIX open()
कॉल से मिलता है । मानक सी का उपयोग करके fopen()
आपको एक FILE
संरचना वापस मिलती है । इस FILE
संरचना में अन्य चीज़ों जैसे अंत फ़ाइल और त्रुटि संकेतक, स्ट्रीम स्थिति आदि के बीच यह फ़ाइल विवरणक है।
तो उपयोग करने fopen()
से आपको एक निश्चित मात्रा में अमूर्तता मिलती है open()
। सामान्य तौर पर आप का उपयोग किया जाना चाहिए fopen()
क्योंकि यह अधिक पोर्टेबल है और आप सभी अन्य मानक सी फ़ंक्शन का उपयोग कर सकते हैं जो FILE
संरचना, अर्थात fprintf()
और परिवार का उपयोग करता है ।
कोई प्रदर्शन समस्याएँ भी नहीं हैं।
फ़ाइल डिस्क्रिप्टर बनाम फ़ाइल पॉइंटर
फ़ाइल विवरणक:
फ़ाइल डिस्क्रिप्टर open()
सिस्टम कॉल द्वारा लौटाया गया एक पूर्णांक मान है ।
int fd = open (filePath, mode);
फ़ाइल पॉइंटर:
फ़ाइल पॉइंटर fopen()
, लाइब्रेरी फ़ंक्शन द्वारा लौटाए गए C संरचना के लिए एक पॉइंटर है , जिसका उपयोग किसी फ़ाइल की पहचान करने के लिए किया जाता है , फ़ाइल डिस्क्रिप्टर, बफरिंग कार्यक्षमता और I / O ऑपरेशन के लिए आवश्यक सभी अन्य कार्यक्षमता को लपेटता है । फ़ाइल पॉइंटर टाइप FILE का है , जिसकी परिभाषा है। "/usr/include/stdio.h" में पाया जा सकता है । यह परिभाषा एक संकलक से दूसरे में भिन्न हो सकती है।
FILE *fp = fopen (filePath, mode);
// A FILE Structure returned by fopen
typedef struct
{
unsigned char *_ptr;
int _cnt;
unsigned char *_base;
unsigned char *_bufendp;
short _flag;
short _file;
int __stdioid;
char *__newbase;
#ifdef _THREAD_SAFE
void *_lock;
#else
long _unused[1];
#endif
#ifdef __64BIT__
long _unused1[4];
#endif /* __64BIT__ */
} FILE;
ऐसे बिंदु जोड़ना चाहते हैं जो उपयोगी हो सकते हैं।
के बारे में FILE *
मैं इसे डिबग लॉग के लिए कई बार उपयोग करता हूं। उदाहरण,
FILE *fp;
fp = fopen("debug.txt","a");
fprintf(fp,"I have reached till this point");
fclose(fp);
के बारे में FILE DESCRIPTOR
यह आमतौर पर आईपीसी के लिए उपयोग किया जाता है।
* Nix सिस्टम (डिवाइस, फाइल, सॉकेट, आदि) पर फ़ाइलों के लिए निम्न-स्तरीय नियंत्रण देता है, इसलिए इससे अधिक शक्तिशाली है FILE *
।
fdopen()
IPC और उपकरणों जैसी चीजों का उपयोग करने के लिए नहीं कर सकते हैं FILE*
?
FILE*
कर सकते हैं, लेकिन आप FILE*
एक फ़ाइल डिस्क्रिप्टर ( fdopen()
) से बना सकते हैं और बाद में वसीयतनामा को बंद कर FILE
देंगे। इसलिए, आप आईपीसी कर सकते हैं , लेकिन आपको किसी भी प्रत्यक्ष आईपीसी को सुविधाजनक बनाने के लिए फ़ाइल विवरणकर्ताओं से थोड़ा सा निपटना होगा।
FILE *
जब आप, पाठ फ़ाइलें और उपयोगकर्ता इनपुट / आउटपुट के साथ काम है क्योंकि यह आप एपीआई कार्यों की तरह उपयोग करने के लिए अनुमति देता है और अधिक उपयोगी है sprintf()
, sscanf()
, fgets()
, feof()
आदि
फ़ाइल डिस्क्रिप्टर एपीआई निम्न-स्तर है, इसलिए यह सॉकेट्स, पाइप, मेमोरी-मैप्ड फ़ाइलों (और नियमित रूप से फाइलें, निश्चित रूप से) के साथ काम करने की अनुमति देता है।
चर्चा समाप्त करने के लिए बस एक नोट (यदि रुचि हो) ...।
fopen
असुरक्षित हो सकता है, और आप शायद का उपयोग करना चाहिए fopen_s
या open
सेट विशेष बिट्स के साथ। C1X पेशकश कर रहा है x
मोड, तो आप कर सकते हैं fopen
मोड के साथ "rx"
, "wx"
आदि
यदि आप उपयोग करते हैं open
, तो आप विचार कर सकते हैं open(..., O_EXCL | O_RDONLY,... )
या open(..., O_CREAT | O_EXCL | O_WRONLY,... )
।
उदाहरण के लिए, fopen () और फ़ाइल निर्माण के बारे में धारणा न बनाएं ।
fopen_s
साथ उपलब्ध होना प्रतीत नहीं होता है POSIX
, मुझे लगता है कि सबसे अधिक पोर्टेबल स्पिरिटेशन open(2)
और फिर होगा fdopen(2)
। (खिड़कियों को एक तरफ छोड़कर)। इसके अलावा, तेजी से fopen_s()
या open(2)
उसके बाद क्या होगा fdopen(2)
?
सिस्टम कॉल ज्यादातर फाइल डिस्क्रिप्टर का उपयोग कर रहे हैं, उदाहरण के लिए read
और write
। लाइब्रेरी फ़ंक्शन फ़ाइल पॉइंटर्स ( printf
, scanf
) का उपयोग करेगा । लेकिन, लाइब्रेरी फ़ंक्शंस केवल आंतरिक रूप से सिस्टम कॉल का उपयोग कर रहे हैं।
मुझे यहां एक अच्छा संसाधन मिला , जिससे दोनों के बीच मतभेदों के उच्च स्तर का अवलोकन हुआ:
जब आप किसी फ़ाइल में इनपुट या आउटपुट करना चाहते हैं, तो आपके पास अपने प्रोग्राम और फ़ाइल के बीच कनेक्शन का प्रतिनिधित्व करने के लिए दो बुनियादी तंत्रों का विकल्प होता है: फ़ाइल डिस्क्रिप्टर और स्ट्रीम। फ़ाइल डिस्क्रिप्टर को टाइप इंट की वस्तुओं के रूप में दर्शाया जाता है, जबकि धाराओं को FILE * ऑब्जेक्ट के रूप में दर्शाया जाता है।
फ़ाइल डिस्क्रिप्टर इनपुट और आउटपुट संचालन के लिए एक आदिम, निम्न-स्तरीय इंटरफ़ेस प्रदान करते हैं। फाइल डिस्क्रिप्टर और स्ट्रीम दोनों एक डिवाइस (जैसे एक टर्मिनल), या किसी अन्य प्रक्रिया के साथ संचार के लिए एक पाइप या सॉकेट के लिए एक कनेक्शन का प्रतिनिधित्व कर सकते हैं, साथ ही साथ एक सामान्य फ़ाइल भी। लेकिन, यदि आप नियंत्रण कार्य करना चाहते हैं जो एक विशेष प्रकार के उपकरण के लिए विशिष्ट है, तो आपको एक फ़ाइल विवरणक का उपयोग करना चाहिए; इस तरह धाराओं का उपयोग करने के लिए कोई सुविधाएं नहीं हैं। यदि आपके प्रोग्राम को विशेष मोड में इनपुट या आउटपुट करने की आवश्यकता है, जैसे कि नॉनब्लॉकिंग (या पोलेड) इनपुट (फाइल स्टेटस फ्लैग देखें) तो आपको फाइल डिस्क्रिप्टर का भी उपयोग करना चाहिए।
धाराएँ एक उच्च-स्तरीय इंटरफ़ेस प्रदान करती हैं, जो आदिम फ़ाइल डिस्क्रिप्टर सुविधाओं के शीर्ष पर स्तरित होती हैं। स्ट्रीम इंटरफ़ेस सभी प्रकार की फ़ाइलों को बहुत समान रूप से मानता है - एकमात्र अपवाद बफ़रिंग की तीन शैलियाँ हैं जिन्हें आप चुन सकते हैं (स्ट्रीम बफरिंग देखें)।
स्ट्रीम इंटरफ़ेस का उपयोग करने का मुख्य लाभ यह है कि धाराओं पर वास्तविक इनपुट और आउटपुट ऑपरेशन (नियंत्रण संचालन के लिए विरोध के रूप में) करने के लिए फ़ंक्शन का सेट फ़ाइल डिस्क्रिप्टर के लिए संबंधित सुविधाओं की तुलना में बहुत समृद्ध और अधिक शक्तिशाली है। फ़ाइल डिस्क्रिप्टर इंटरफ़ेस वर्णों के ब्लॉक को स्थानांतरित करने के लिए केवल सरल फ़ंक्शन प्रदान करता है, लेकिन स्ट्रीम इंटरफ़ेस शक्तिशाली स्वरूपित इनपुट और आउटपुट फ़ंक्शन (प्रिंटफ और स्कैनफ) के साथ-साथ चरित्र- और लाइन-ओरिएंटेड इनपुट और आउटपुट के लिए फ़ंक्शन भी प्रदान करता है।
चूँकि फाइल डिस्क्रिप्टर के संदर्भ में धाराएँ लागू की जाती हैं, आप फाइल डिस्क्रिप्टर को एक स्ट्रीम से निकाल सकते हैं और फाइल डिस्क्रिप्टर पर सीधे निम्न-स्तरीय ऑपरेशन कर सकते हैं। आप शुरुआत में एक फाइल डिस्क्रिप्टर के रूप में एक कनेक्शन भी खोल सकते हैं और फिर उस फाइल डिस्क्रिप्टर से जुड़ी एक स्ट्रीम बना सकते हैं।
सामान्य तौर पर, आपको फ़ाइल डिस्क्रिप्टर के बजाय स्ट्रीम का उपयोग करना चाहिए, जब तक कि कुछ विशिष्ट ऑपरेशन नहीं करना चाहते हैं जो केवल फ़ाइल डिस्क्रिप्टर पर किया जा सकता है। यदि आप एक शुरुआत प्रोग्रामर हैं और सुनिश्चित नहीं हैं कि किस फ़ंक्शन का उपयोग करना है, तो हमारा सुझाव है कि आप स्वरूपित इनपुट फ़ंक्शंस (फ़ॉर्मेट किए गए इनपुट देखें) और फ़ॉर्मेट किए गए आउटपुट फ़ंक्शंस (फ़ॉर्मेट किए गए आउटपुट देखें) पर ध्यान केंद्रित करें।
यदि आप अपने कार्यक्रमों की जीएनयू के अलावा अन्य प्रणालियों के पोर्टेबिलिटी के बारे में चिंतित हैं, तो आपको यह भी पता होना चाहिए कि फ़ाइल विवरणक स्ट्रीम के रूप में पोर्टेबल नहीं हैं। आप ISO C को स्ट्रीम के समर्थन में चलाने वाले किसी भी सिस्टम की अपेक्षा कर सकते हैं, लेकिन गैर-GNU सिस्टम फ़ाइल डिस्क्रिप्टर का समर्थन नहीं कर सकते हैं या केवल GNU फ़ंक्शंस के सबसेट को लागू कर सकते हैं जो फ़ाइल डिस्क्रिप्टर पर काम करते हैं। GNU C लाइब्रेरी में फ़ाइल डिस्क्रिप्टर फ़ंक्शंस में से अधिकांश POSIX.1 मानक में शामिल हैं, हालाँकि।