2010-12-29 16 views
18

मैं यह जांचने के लिए एक प्रोग्राम लिख रहा हूं कि कुछ फ़ाइल है या निर्देशिका है या नहीं। क्या इससे ऐसा करने का कोई बेहतर तरीका है?जांचना कि कोई फ़ाइल निर्देशिका है या सिर्फ एक फ़ाइल

#include <stdio.h> 

#include <sys/types.h> 
#include <dirent.h> 
#include <errno.h> 

int isFile(const char* name) 
{ 
    DIR* directory = opendir(name); 

    if(directory != NULL) 
    { 
    closedir(directory); 
    return 0; 
    } 

    if(errno == ENOTDIR) 
    { 
    return 1; 
    } 

    return -1; 
} 

int main(void) 
{ 
    const char* file = "./testFile"; 
    const char* directory = "./"; 

    printf("Is %s a file? %s.\n", file, 
    ((isFile(file) == 1) ? "Yes" : "No")); 

    printf("Is %s a directory? %s.\n", directory, 
    ((isFile(directory) == 0) ? "Yes" : "No")); 

    return 0; 
} 

उत्तर

36

आप stat() फ़ंक्शन को कॉल करें और क्रम में stat संरचना के st_mode मैदान पर S_ISREG() मैक्रो का उपयोग कर सकते हैं

#include <sys/types.h> 
#include <sys/stat.h> 
#include <unistd.h> 

int is_regular_file(const char *path) 
{ 
    struct stat path_stat; 
    stat(path, &path_stat); 
    return S_ISREG(path_stat.st_mode); 
} 

नोट वहाँ नियमों के अलावा अन्य फ़ाइल प्रकार के होते हैं: एक नियमित रूप से फाइल करने के लिए आर और निर्देशिका, जैसे डिवाइस, पाइप, प्रतीकात्मक लिंक, सॉकेट इत्यादि। आप उन्हें ध्यान में रखना चाहेंगे।

+4

symlink मामलों पर विचार करते समय, stat() के बजाय lstat() का उपयोग करें क्योंकि यह symlink का पालन नहीं करता है। – Sparky

+3

कम से कम एक अच्छी चर्चा है [जांच कर रहा है कि कोई निर्देशिका मौजूद है] (http://stackoverflow.com/questions/3828192/checking-if-a-directory-exists-in-unix-system-call/), जहां ' stat() 'और' lstat() 'पर चर्चा की जाती है, और POSIX फ़ाइल प्रकारों का पूरा सेट उल्लिखित है। मैं इस सवाल को उस पर डुप्लिकेट करने का लुत्फ उठा रहा हूं। कोड को 'stat()' के परिणाम की भी जांच करनी चाहिए, और त्रुटियों को उचित तरीके से संभालना चाहिए। –

+0

@ जोनाथन, यह जवाब वास्तव में मेरे से अधिक पूर्ण है, और पांच साल पहले मेरे तीन महीने पहले पोस्ट किया गया था। और ऐसा नहीं है कि मेरा खुद का जवाब वैसे भी गायब हो जाएगा। मैं देखता हूं कि आप '[सी]' टैग में Mjölnir का प्रबंधन करते हैं, इसलिए एकतरफा अभिनय करने से पहले टिप्पणी करने के लिए धन्यवाद। हालांकि, आप अंत में सही हैं। कोई चिंता नहीं, आपको क्या करना है :) –

4

हां, बेहतर है। चेक stat या fstat समारोह

14

का प्रयोग करें S_ISDIR मैक्रो: अपने पथ अंक अगर निर्धारित करने के लिए

int isDirectory(const char *path) { 
    struct stat statbuf; 
    if (stat(path, &statbuf) != 0) 
     return 0; 
    return S_ISDIR(statbuf.st_mode); 
} 
+0

आप जानकारी के साथ 'statbuf' संरचना को भरना भूल गए। – RedX

+1

यह ठीक काम करता है, स्टेट फ़ंक्शन जानकारी भरता है। – ismail

+2

आदर्श रूप से, कोड जांच करेगा कि 'stat' ने काम किया:' अगर (stat (path, and statbuf)! = 0) 0 लौटाएं; '- क्योंकि एक अस्तित्वहीन वस्तु निर्देशिका नहीं है, और यदि आपके पास नहीं है 'stat()' की अनुमति, यह अस्तित्व में भी नहीं हो सकता है (भले ही त्रुटि रिपोर्ट की अनुमति से संबंधित है)। –

1

आम तौर पर आप परिणाम का उपयोग करके इस चेक को परमाणु रूप से निष्पादित करना चाहते हैं, इसलिए stat() बेकार है। इसके बजाए, open() फ़ाइल केवल पढ़ने के लिए पहले और fstat() का उपयोग करें। यदि यह एक निर्देशिका है, तो आप इसे पढ़ने के लिए fdopendir() का उपयोग कर सकते हैं। या आप इसे लिखने के लिए लिखने के लिए खोलने का प्रयास कर सकते हैं, और यदि यह निर्देशिका है तो खुले विफल हो जाएंगे। कुछ सिस्टम (POSIX 2008, Linux) में O_DIRECTORY एक्सटेंशन open पर भी है जो नाम विफल होने पर कॉल विफल हो जाता है।

opendir() के साथ आपकी विधि भी अच्छी है यदि आप निर्देशिका चाहते हैं, लेकिन आपको इसे बाद में बंद नहीं करना चाहिए; आपको आगे बढ़ना चाहिए और इसका इस्तेमाल करना चाहिए।

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