获取C中的大文件大小

在有人抱怨“重复”之前,我一直在彻底检查SO,但似乎还没有干净的答案,尽管问题看起来很简单。

我正在寻找一个可移植的C代码 ,它能够提供文件的大小,即使这样的文件大于4GB。

通常的方法(fseek,ftell)工作正常,只要文件仍然<2GB。 它在各处得到了相当好的支持,所以我试图找到相同的东西。

不幸的是,所有编译器都不支持更新的方法(fseeko,ftello)。 例如,MinGW错过了它(显然是MSVC)。 此外,一些评论让我相信新的返回类型(off_t)不一定支持> 2GB的大小,它可能依赖于一些外部参数来进行检查。

MSVC不支持明确的方法(fseeko64,ftello64)。 MS提供等效的_fseeki64和_ftelli64。 这已经很糟糕,但它变得更糟:一些Linux配置似乎在运行时严重支持这些function。 例如,我在PowerPC上的Debian Squeeze,使用GCC 4.4,将使用fseeko64产生一个“filesize”方法,它始终返回0(虽然它适用于Ubuntu64)。 MinGW似乎回答了2GB以上的随机垃圾。

好吧,就可移植性而言,我有点无能为力。 如果我需要制作一堆#if #else,那么为什么不首先直接使用OS和编译器细节方法,例如用于MSVC的GetFileSize()。

你说过:没有便携方法; 如果我是你,我会在Windows上使用GetFileSize ,在POSIX上使用stat

您应该能够在Linux 上使用stat64 , 在Windows 上使用stat64来获取超过2 GB的文件的文件大小信息,并且这两个函数的使用非常相似。 您也可以使用几个#define来在Windows上使用stat64

 #if __WIN32__ #define stat64 _stat64 #endif 

但是,尽管这应该有效,但应该注意的是,Windows上的_stat函数系列实际上只是其他函数的包装,并且会增加额外的资源和时间开销。

 int ch; FILE *f = fopen("file_to_analyse", "rb"); /* error checking ommited for brevity */ unsigned long long filesize = 0; /* or unsigned long for C89 compatability*/ while ((ch = fgetc(f)) != EOF) filesize++; fclose(f); /* error checking ommited for brevity */ 

我已经实施并测试了以下内容:

 #if __WIN32__ #define stat64 _stat64 #endif 

使用MinGW64 gcc编译器4.8.1和Linux gcc 4.6.3编译和工作。

在OSX上,不需要重新定义stat。

对于lstat和fstat函数,我希望类似的宏#defines能够工作。

使用lseek() (或_lseek() )和SEEK_END怎么样? 它返回寻求的偏移量。

在Linux下_FILE_OFFSET_BITS需要定义为64lseek()返回64位值(无论如何应该是默认值)。

 #include sys/stat.h off_t fsize(const char *filename) { struct stat st; if (stat(filename, &st) == 0) return st.st_size; return -1; }