Answers:
基于NilObject的代码:
#include <sys/stat.h>
#include <sys/types.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
缺少变量名的定义。-1
错误而不是0
,这对于一个空文件将是不明确的。off_t
是带符号的类型,因此这是可能的。如果要fsize()
打印错误消息,可以使用以下命令:
#include <sys/stat.h>
#include <sys/types.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位系统上,应使用option进行编译-D_FILE_OFFSET_BITS=64
,否则off_t
只能保存最大2 GB的值。有关详细信息,请参见Linux中大文件支持的“使用LFS”部分。
fseek
+ ftell
。
fseek
+ ftell
。 号的C标准明确规定,fseek()
以SEEK_END
一个二进制文件的是未定义的行为。 7.19.9.2 fseek
函数 ...二进制流不必有意义地支持fseek
whence值为SEEK_END
和的调用,如下所述(来自p的脚注234)。链接的C标准,并且其特异性标签267 fseek
到SEEK_END
在二进制流作为未定义的行为。。
不要使用int
。如今,超过2 GB的文件通常很脏
不要使用unsigned int
。大小超过4 GB的文件很常见,是一些不太常见的污垢
IIRC标准库将其定义off_t
为无符号的64位整数,这是每个人都应使用的整数。几年后,当我们开始挂起16 EB文件时,我们可以将其重新定义为128位。
如果您使用的是Windows,则应使用GetFileSizeEx-它实际上使用带符号的64位整数,因此它们将开始遇到8艾字节文件的问题。愚蠢的微软!:-)
Matt的解决方案应该可以用,除了它是C ++而不是C,而且不需要初始告诉。
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;
}
也为您固定了支架。;)
更新:这并不是真正的最佳解决方案。在Windows上它仅限于4GB的文件,并且可能比仅使用特定于平台的调用(例如GetFileSizeEx
或)要慢stat64
。
long int
从返回ftell()
。 (unsigned long)
强制转换不能改善范围,因为功能已经限制了该范围。 ftell()
传回-1时发生错误,并且会因转换而混淆。建议fsize()
返回与相同的类型ftell()
。
**不这样做(为什么?):
引用我在网上找到的C99标准文档:“与一样,将文件位置指示符设置为文件末尾
fseek(file, 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
}
fseeko
和ftello
(或者fseek
,ftell
如果您没有前者而感到困惑,并且对可以使用的文件大小的限制感到满意)是确定文件长度的正确方法。stat
基于解决方案的解决方案不能在许多“文件”(例如块设备)上运行,并且不能移植到非POSIX的系统上。
该POSIX标准都有自己的方法来获取文件的大小。
包括sys/stat.h
标题以使用该功能。
stat(3)
。st_size
属性。注意:大小限制为4GB
。如果不是Fat32
文件系统,则使用64位版本!
#include <stdio.h>
#include <sys/stat.h>
int main(int argc, char** argv)
{
struct stat info;
stat(argv[1], &info);
// 'st' is an acronym of 'stat'
printf("%s: size=%ld\n", argv[1], info.st_size);
}
#include <stdio.h>
#include <sys/stat.h>
int main(int argc, char** argv)
{
struct stat64 info;
stat64(argv[1], &info);
// 'st' is an acronym of 'stat'
printf("%s: size=%ld\n", argv[1], info.st_size);
}
的ANSI C不直接提供,以确定文件的长度的方式。
我们必须要动脑子。现在,我们将使用搜索方法!
#include <stdio.h>
int main(int argc, char** argv)
{
FILE* fp = fopen(argv[1]);
int f_size;
fseek(fp, 0, SEEK_END);
f_size = ftell(fp);
rewind(fp); // to back to start again
printf("%s: size=%ld", (unsigned long)f_size);
}
文件是
stdin
还是管道。POSIX,ANSI C无法正常工作。 如果文件是管道或
,它将返回。0
stdin
意见:您应该改用POSIX标准。因为,它具有64位支持。
struct _stat64
而__stat64()
对于_WINDOWS。
而且,如果您要构建Windows应用程序,请使用GetFileSizeEx API,因为CRT文件的I / O杂乱无章,特别是对于确定文件长度,由于不同系统上文件表示的特殊性;)
在Google中进行的快速搜索找到了使用fseek和ftell的方法以及一个带有此问题的线程,并给出了答案,它不能用另一种方式仅用C来完成。
试试这个 -
fseek(fp, 0, SEEK_END);
unsigned long int file_size = ftell(fp);
rewind(fp);
首先,寻找文件的结尾;然后,报告文件指针的位置。最后(这是可选的),它后退到文件的开头。注意,它fp
应该是一个二进制流。
file_size包含文件包含的字节数。请注意,由于(根据climits.h)无符号长类型限制为4294967295字节(4 GB),因此,如果您可能要处理更大的文件,则需要查找其他变量类型。
ftell
它不返回表示可以从文件读取的字节数的值。