在C中获取文件大小的正确方法

2024-01-06

我正在做一个套接字编程作业,其中我必须在 sparc 和 Linux 机器之间发送一个文件。在以字符流发送文件之前,我必须获取文件大小并告诉客户端。以下是我尝试获取尺寸的一些方法,但我不确定哪一种是合适的。

出于测试目的,我创建了一个内容为“test”的文件(空格+(字符串)test)

方法 1 - 使用 fseeko() 和 ftello()

这是我在上面找到的一个方法https://www.securecoding.cert.org/confluence/display/c/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a +常规+文件 https://www.securecoding.cert.org/confluence/display/c/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file虽然 fssek() 存在“将文件位置指示器设置为文件结尾,与 fseek(file, 0, SEEK_END) 一样,对于二进制流具有未定义的行为”的问题,但据说 fseeko() 已经解决了这个问题但它只适用于 POSIX 系统(这很好,因为我使用的环境是 sparc 和 linux)

fd = open(file_path, O_RDONLY);
fp = fopen(file_path, "rb");
/* Ensure that the file is a regular file */
if ((fstat(fd, &st) != 0) || (!S_ISREG(st.st_mode))) {
  /* Handle error */
}
if (fseeko(fp, 0 , SEEK_END) != 0) {
  /* Handle error */
}
file_size = ftello(fp);
fseeko(fp, 0, SEEK_SET);
printf("file size %zu\n", file_size);

此方法效果很好,并且可以正确获取尺寸。但是,它仅限于常规文件。我尝试用谷歌搜索术语“常规文件”,但我仍然不太完全理解它。而且我不知道这个功能对于我的项目是否可靠。

方法 2 - 使用 strlen()

由于最大。我的项目中的文件大小为 4MB,因此我可以调用 4MB 缓冲区。之后,文件被读入缓冲区,我尝试使用 strlen 来获取文件大小(或更准确地说是内容的长度)。由于 strlen() 是可移植的,我可以使用此方法吗?代码片段是这样的

fp = fopen(file_path, "rb");
fread(file_buffer, 1024*1024*4, 1, fp);
printf("strlen %zu\n", strlen(file_buffer));

这个方法也有效并返回

strlen 8

但是,我在互联网上看不到任何使用此方法的类似方法。所以我想也许我错过了一些东西,或者这种方法有一些我没有意识到的局限性。


常规文件意味着它没有像设备、套接字、管道等特殊的东西,而是“普通”文件。 看来根据您的任务描述,在发送之前您必须检索正常文件的大小。 所以你的方法是对的:

FILE* fp = fopen(...);
if(fp) {
  fseek(fp, 0 , SEEK_END);
  long fileSize = ftell(fp);
  fseek(fp, 0 , SEEK_SET);// needed for next read from beginning of file
  ...
  fclose(fp);
}

但您可以在不打开文件的情况下执行此操作:

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

struct stat buffer;
int         status;

status = stat("path to file", &buffer);
if(status == 0) {
  // size of file is in member buffer.st_size;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在C中获取文件大小的正确方法 的相关文章