2008-08-11 13 views

उत्तर

122

NilObject के कोड के आधार पर:

#include <sys/stat.h> 

off_t fsize(const char *filename) { 
    struct stat st; 

    if (stat(filename, &st) == 0) 
     return st.st_size; 

    return -1; 
} 

परिवर्तन:

  • फ़ाइल नाम तर्क एक const char बनाया।
  • struct stat परिभाषा को ठीक किया गया, जो परिवर्तनीय नाम गायब था।
  • -10 की बजाय त्रुटि पर लौटाता है, जो एक खाली फ़ाइल के लिए अस्पष्ट होगा। off_t एक हस्ताक्षरित प्रकार है इसलिए यह संभव है।

आप fsize() चाहते हैं त्रुटि पर एक संदेश मुद्रित करने के लिए, तो आप इस का उपयोग कर सकते हैं:

#include <sys/stat.h> 
#include <string.h> 
#include <stdio.h> 
#include <errno.h> 

off_t fsize(const char *filename) { 
    struct stat st; 

    if (stat(filename, &st) == 0) 
     return st.st_size; 

    fprintf(stderr, "Cannot determine size of %s: %s\n", 
      filename, strerror(errno)); 

    return -1; 
} 

32-बिट सिस्टम पर आप विकल्प -D_FILE_OFFSET_BITS=64 के साथ इस संकलन चाहिए, अन्यथा off_t केवल मान का आयोजन करेगा 2 जीबी तक। विवरण के लिए Large File Support in Linux के "एलएफएस का उपयोग करना" अनुभाग देखें।

+12

यह लिनक्स/यूनिक्स विशिष्ट है - शायद यह इंगित करने लायक है कि प्रश्न के बाद से ओएस निर्दिष्ट नहीं किया गया था। –

+1

आप शायद रिटर्न प्रकार को ssize_t में बदल सकते हैं और किसी भी परेशानी के बिना ऑफ_टी से आकार कास्ट कर सकते हैं। यह एक ssize_t :-) का उपयोग करने के लिए और अधिक समझ में प्रतीत होता है (आकार_टी के साथ उलझन में नहीं है जिसे हस्ताक्षर किया गया है और त्रुटि को इंगित करने के लिए उपयोग नहीं किया जा सकता है।) –

+1

अधिक पोर्टेबल कोड के लिए, प्रस्तावित के रूप में 'fseek' + ftell' का उपयोग करें डेरेक। –

-1

आपको फ़ाइल के विवरण पुनर्प्राप्त करने के लिए लाइब्रेरी फ़ंक्शन का उपयोग करने की आवश्यकता होगी। चूंकि सी पूरी तरह से प्लेटफार्म स्वतंत्र है, आपको हमें यह बताना होगा कि आप किस मंच/ऑपरेटिंग सिस्टम के लिए विकास कर रहे हैं!

5

आप एसटीडी सी लाइब्रेरी का उपयोग कर के साथ ठीक कर रहे हैं:

#include <sys/stat.h> 
off_t fsize(char *file) { 
    struct stat filestat; 
    if (stat(file, &filestat) == 0) { 
     return filestat.st_size; 
    } 
    return 0; 
} 
+19

यह मानक सी नहीं है। यह POSIX मानक का हिस्सा है, लेकिन सी मानक नहीं है। –

-3

आप फ़ाइल को खोलने 0 पर जा सकते हैं

#define SEEKBOTTOM 2 

fseek(handle, 0, SEEKBOTTOM) 

मूल्य के साथ फ़ाइल के नीचे से रिश्तेदार ऑफसेट fseek से वापस फ़ाइल का आकार है।

मैंने लंबे समय तक सी में कोड नहीं किया, लेकिन मुझे लगता है कि इसे काम करना चाहिए।

+12

आपको SEEKBOTTOM जैसे कुछ को परिभाषित नहीं करना चाहिए। # शामिल fseek (हैंडल, 0, SEEK_END); – sigjuice

24

मैट का समाधान काम करना चाहिए, सिवाय इसके कि यह सी के बजाय सी ++ है, और प्रारंभिक बताना आवश्यक नहीं होना चाहिए।

unsigned long fsize(char* file) 
{ 
    FILE * f = fopen(file, "r"); 
    fseek(f, 0, SEEK_END); 
    unsigned long len = (unsigned long)ftell(f); 
    fclose(f); 
    return len; 
} 

भी आपके लिए अपनी ब्रेस फिक्स्ड। ;)

अद्यतन: यह वास्तव में सबसे अच्छा समाधान नहीं है। यह विंडोज़ पर 4 जीबी फाइलों तक सीमित है और यह केवल GetFileSizeEx या stat64 जैसे मंच-विशिष्ट कॉल का उपयोग करने की तुलना में धीमी है।

+0

हां, आपको चाहिए। हालांकि, जब तक कि वास्तव में आकर्षक कारण नहीं है, प्लेटफ़ॉर्म-विशिष्ट नहीं लिखते हैं, हालांकि, आपको शायद खुले/तलाश-अंत/बताना/बंद पैटर्न के बजाय प्लेटफॉर्म-विशिष्ट कॉल का उपयोग करना चाहिए। –

+1

देर से उत्तर के बारे में खेद है, लेकिन मुझे यहां एक बड़ी समस्या है।यह प्रतिबंधित फ़ाइलों तक पहुंचने पर ऐप को लटकने का कारण बनता है (जैसे पासवर्ड संरक्षित या सिस्टम फाइलें)। क्या आवश्यकता होने पर उपयोगकर्ता को पासवर्ड के लिए पूछने का कोई तरीका है? – Justin

+0

@ जस्टिन, आपको शायद उस मुद्दे के बारे में विशेष रूप से एक नया प्रश्न खोलना चाहिए जिसमें आप चल रहे हैं, और आप जिस प्लेटफ़ॉर्म पर हैं, आप फ़ाइलों तक कैसे पहुंच रहे हैं, और व्यवहार क्या है, इसके बारे में विवरण प्रदान करें। –

12

** ऐसा मत करो (why?):

C99 मानक दस्तावेज़ जिसे मैं ऑनलाइन पाया हवाला देते हुए: ", अंत के- फाइल करने के लिए फ़ाइल स्थिति सूचक स्थापना fseek साथ के रूप में (फ़ाइल, 0, SEEK_END), (क्योंकि संभव अशक्त पात्रों अनुगामी के) या कि विश्वासपूर्वक प्रारंभिक पारी राज्य में खत्म नहीं होता राज्य पर निर्भर एन्कोडिंग के साथ किसी भी स्ट्रीम के लिए एक द्विआधारी स्ट्रीम के लिए व्यवहार अपरिभाषित है। **

बदलें int की परिभाषा ताकि त्रुटि संदेशों को प्रेषित किया जा सके, और फिर फ़ाइल आकार निर्धारित करने के लिए fseek() और ftell() का उपयोग करें।

int fsize(char* file) { 
    int size; 
    FILE* fh; 

    fh = fopen(file, "rb"); //binary mode 
    if(fh != NULL){ 
    if(fseek(fh, 0, SEEK_END)){ 
     fclose(fh); 
     return -1; 
    } 

    size = ftell(fh); 
    fclose(fh); 
    return size; 
    } 

    return -1; //error 
} 
+5

@mezhaka: वह सीईआरटी रिपोर्ट बस गलत है। 'fseeko' और' ftello' (या 'fseek' और' ftell' अगर आप पूर्व के बिना फंस गए हैं और फ़ाइल आकारों पर सीमाओं से खुश हैं) तो आप फ़ाइल की लंबाई निर्धारित करने का सही तरीका हैं। 'stat'- आधारित समाधान ** कई" फाइलों "(जैसे ब्लॉक डिवाइस) पर काम नहीं करते हैं और गैर-पॉज़िक्स-आईएसएच सिस्टम के लिए पोर्टेबल नहीं हैं। –

+1

कई गैर-पॉजिक्स अनुपालन प्रणालियों (जैसे मेरा बहुत ही सरल मैबेड) पर फ़ाइल आकार प्राप्त करने का यही एकमात्र तरीका है – Earlz

3

गूगल में एक त्वरित खोज a method using fseek and ftell और कि यह सिर्फ सी में किसी अन्य तरीके से नहीं किया जा सकता उत्तरों के साथ इस सवाल के साथ एक धागा मिल गया।

आप पोर्टेबिलिटी लाइब्रेरी का उपयोग कर सकते हैं जैसे NSPR (लाइब्रेरी जो फ़ायरफ़ॉक्स को पावर करता है) या its implementation (बल्कि बालों वाली) की जांच करें।

66

int का उपयोग न करें। आकार में 2 गीगाबाइट से अधिक फ़ाइलें इन दिनों गंदगी के रूप में आम हैं

unsigned int का उपयोग न करें। आकार में 4 गीगाबाइट्स से अधिक फ़ाइलें सामान्य हैं, कुछ कम-कम-सामान्य गंदगी

आईआईआरसी मानक पुस्तकालय off_t को एक हस्ताक्षरित 64 बिट पूर्णांक के रूप में परिभाषित करता है, जो कि सभी को उपयोग करना चाहिए। हम कुछ वर्षों में 128 बिट्स को फिर से परिभाषित कर सकते हैं जब हम 16 एक्साबाइट फाइलें लटकते हैं।

यदि आप विंडोज़ पर हैं, तो आपको GetFileSizeEx का उपयोग करना चाहिए - यह वास्तव में एक हस्ताक्षरित 64 बिट पूर्णांक का उपयोग करता है, इसलिए वे 8 एक्साबाइट फ़ाइलों के साथ समस्याओं को मारना शुरू कर देंगे। मूर्ख मूर्ख! :-)

+0

मैंने कंपाइलर्स का उपयोग किया है जहां off_t 32 बिट्स है। अनुमोदित, यह एम्बेडेड सिस्टम पर है जहां 4 जीबी फाइलें कम आम हैं। वैसे भी, POSIX भी भ्रम में जोड़ने के लिए off64_t और इसी तरह के तरीकों को परिभाषित करता है। –

4

और आप एक Windows अनुप्रयोग का निर्माण कर रहे हैं, सीआरटी फ़ाइल के रूप में GetFileSizeEx एपीआई का उपयोग मैं/हे गंदा, विशेष रूप से फ़ाइल लंबाई निर्धारित करने, विभिन्न प्रणालियों फ़ाइल अभ्यावेदन में विशेषताओं के कारण के लिए है;)

1

मैंने फ़ाइल की लंबाई खोजने के लिए कोड के इस सेट का उपयोग किया। प्रश्न पर

//opens a file with a file descriptor 
FILE * i_file; 
i_file = fopen(source, "r"); 

//gets a long from the file descriptor for fstat 
long f_d = fileno(i_file); 
struct stat buffer; 
fstat(f_d, &buffer); 

//stores file size 
long file_length = buffer.st_size; 
fclose(i_file); 
-2

देखते हुए, ftell आसानी से बाइट की संख्या प्राप्त कर सकते हैं।

long size ; 
    size = ftell(FILENAME); 
    printf("total size is %ld bytes",size); 
+0

'ftell' एक फ़ाइल डिस्क्रिप्टर की अपेक्षा करता है, फ़ाइल नाम नहीं, तर्क के रूप में। – Barmar

1

यहां एक सरल और साफ फ़ंक्शन है जो फ़ाइल आकार देता है। ;

fseek(fp, 0, SEEK_END); 
unsigned long int file_size = ftell(fp); 
rewind(fp); 

यह क्या करता है पहला, फ़ाइल के अंत की तलाश कर रहा है -

long get_file_size(char *path) 
{ 
    FILE *fp; 
    /* Open file for reading */ 
    fp = fopen(path, "r"); 
    fseek(fp, 0, SEEK_END); 
    return ftell(fp); 
} 
+0

क्या आपको फ़ाइल को बंद करने की आवश्यकता नहीं है? –

0

इस प्रयास करें फिर, रिपोर्ट करें कि फ़ाइल सूचक कहाँ है। अंत में (यह वैकल्पिक है) यह फ़ाइल की शुरुआत में वापस आता है। ध्यान दें कि fp एक बाइनरी स्ट्रीम होना चाहिए।

file_size फ़ाइल में बाइट्स की संख्या शामिल है। ध्यान दें कि चूंकि (climits.h के अनुसार) हस्ताक्षरित लंबे प्रकार तक 42 9 4 9 672 9 5 बाइट्स (4 गीगाबाइट्स) तक सीमित है, यदि आपको उससे बड़ी फ़ाइलों से निपटने की संभावना है तो आपको एक अलग चर प्रकार ढूंढना होगा।

+2

यह 8 साल पहले [डेरेक के उत्तर] (http://stackoverflow.com/a/8247/1275169) से अलग कैसे है? –

+0

यह एक बाइनरी स्ट्रीम के लिए अपरिभाषित व्यवहार है, और एक टेक्स्ट स्ट्रीम 'ftell' के लिए बाइट्स की संख्या का मान प्रतिनिधि नहीं लौटाता है जिसे फ़ाइल से पढ़ा जा सकता है। –

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