在C中获取文件大小的正确方法 [英] Proper way to get file size in C

查看:175
本文介绍了在C中获取文件大小的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理套接字编程中的一项工作,在该工作中,我必须在sparc和linux机器之间发送文件.在char流中发送文件之前,我必须获取文件大小并告诉客户端.这是我尝试获取尺寸的一些方法,但是我不确定哪一种是合适的.

I am working on an assignment in socket programming in which I have to send a file between sparc and linux machine. Before sending the file in char stream I have to get the file size and tell the client. Here are some of the ways I tried to get the size but I am not sure which one is the proper one.

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

For testing purpose, I created a file with content " test" (space + (string)test)

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

这是我在

This is a method I found on https://www.securecoding.cert.org/confluence/display/c/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file While the fssek() has a problem of "Setting the file position indicator to end-of-file, as with fseek(file, 0, SEEK_END), has undefined behavior for a binary stream", fseeko() is said to have tackled this problem but it only works on POSIX system (which is fine because the environment I am using is sparc and 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);

此方法可以正常工作并正确获取大小.但是,它仅限于常规文件.我试图用谷歌搜索常规文件"一词,但我仍然不太了解它.而且我不知道此功能对我的项目是否可靠.

This method works fine and get the size correctly. However, it is limited to regular files only. I tried to google the term "regular file" but I still not quite understand it thoroughly. And I do not know if this function is reliable for my project.

方法2-使用strlen()

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

Since the max. size of a file in my project is 4MB, so I can just calloc a 4MB buffer. After that, the file is read into the buffer, and I tried to use the strlen to get the file size (or more correctly the length of content). Since strlen() is portable, can I use this method instead? The code snippet is like this

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

此方法也有效,并返回

strlen 8

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

However, I couldn't see any similar approach on the Internet using this method. So I am thinking maybe I have missed something or there are some limitations of this approach which I haven't realized.

推荐答案

常规文件意味着它与设备,套接字,管道等没有什么不同,只是普通"文件. 看来,根据您的任务描述,在发送之前,您必须检索普通文件的大小. 所以你的方法是正确的:

Regular file means that it is nothing special like device, socket, pipe etc. but "normal" file. It seems that by your task description before sending you must retrieve size of normal file. So your way is right:

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

但是您可以在不打开文件的情况下完成此操作:

but you can do it without opening file:

#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;
}

这篇关于在C中获取文件大小的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆