如何用 C 语言确定文件的大小?

如何计算文件的大小(以字节为单位) ?

#include <stdio.h>


unsigned int fsize(char* file){
//what goes here?
}
148817 次浏览

如果您不介意使用 std c 库:

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

您可以打开该文件,从文件底部到相对偏移量为0

#define SEEKBOTTOM   2


fseek(handle, 0, SEEKBOTTOM)

从 fsearch 返回的值是文件的大小。

我很长一段时间没有用 C 语言编写代码,但我认为它应该可以工作。

Matt 的解决方案应该可以工作,除了它是 C + + 而不是 C,并且不需要初始 tell。

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 文件,而且可能比仅仅使用平台特定的调用(如 GetFileSizeExstat64)要慢。

不要这样做(为什么?) :

引用我在网上找到的 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
}

我发现 使用 ffind 和 ftell 的方法和一个线程与这个问题的答案,它不能只用 C 在另一种方式。

您可以使用像 NSPR(支持 Firefox 的库)这样的可移植库。

不要使用 int。现在超过2G 大小的文件非常普遍

不要使用 unsigned int。超过4GB 大小的文件是常见的一些稍微不常见的污垢

IIRC 标准库将 off_t定义为一个无符号的64位整数,这是每个人都应该使用的。我们可以在几年内将其重新定义为128位,当我们开始拥有16EB 的文件时。

如果你在 Windows 上,你应该使用 GetFileSizeEx-它实际上使用一个64位整数,所以他们会开始遇到问题,与8艾字节的文件。愚蠢的微软!:-)

如果你正在构建一个 Windows 应用程序,使用 GetFileSizeEx API 作为 CRT 文件 I/O 是很麻烦的,特别是在确定文件长度时,由于不同系统上文件表示的特殊性;)

在类 Unix 系统上,可以在已经打开的文件描述符(POSIX 手册,Linux 手册)上使用 POSIX 系统调用: 路径上的 statfstat
(从 open(2)或者 stdio 流上的 fileno(FILE*)获取文件描述符)。

基于 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位系统上,您应该使用选项 -D_FILE_OFFSET_BITS=64编译该文件,否则 off_t将只能保存最多2GB 的值。有关详细信息,请参阅 Linux 中的大文件支持的“使用 LFS”部分。

我使用这组代码来查找文件长度。

//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);

下面是一个返回文件大小的简单而干净的函数。

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

试试这个

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

这样做的目的是: 首先,寻找到文件的末尾; 然后,报告文件指针的位置。最后(这是可选的)它回退到文件的开头。请注意,fp应该是二进制流。

File _ size 包含文件包含的字节数。注意,由于(根据 climits.h)无符号长类型被限制为4294967295字节(4GB) ,如果您可能要处理比这更大的文件,那么您需要找到一个不同的变量类型。

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 (标准)

ANSI C并不直接提供确定文件长度的方法。
我们必须用我们的头脑。现在,我们将使用寻找的方法!

大纲

  • 使用 fseek(3)从头到尾查找文件。
  • 使用 ftell(3)获取当前位置。

例子

#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或管道。
如果文件是管道或者 stdin,它将返回 0

观点 : 您应该改用 POSIX标准,因为它支持64位。

我有一个函数,只有 stdio.h工作得很好。我非常喜欢它,它工作得非常好,非常简洁:

size_t fsize(FILE *File) {
size_t FSZ;
fseek(File, 0, 2);
FSZ = ftell(File);
rewind(File);
return FSZ;
}

从 Windows 文件详细信息中提取的 C + + MFC ,不确定这是否比查找性能更好,但如果是从元数据中提取的,我认为会更快,因为它不需要读取整个文件

ULONGLONG GetFileSizeAtt(const wchar_t *wFile)
{
WIN32_FILE_ATTRIBUTE_DATA fileInfo;
ULONGLONG FileSize = 0ULL;
//https://learn.microsoft.com/nl-nl/windows/win32/api/fileapi/nf-fileapi-getfileattributesexa?redirectedfrom=MSDN
//https://learn.microsoft.com/nl-nl/windows/win32/api/fileapi/ns-fileapi-win32_file_attribute_data?redirectedfrom=MSDN
if (GetFileAttributesEx(wFile, GetFileExInfoStandard, &fileInfo))
{
ULARGE_INTEGER ul;
ul.HighPart = fileInfo.nFileSizeHigh;
ul.LowPart = fileInfo.nFileSizeLow;
FileSize = ul.QuadPart;
}
return FileSize;
}