Linux下C语言获取文件长度:求微软_filelength等效实现及错误排查
让我来帮你搞定这个问题!你的代码出错的核心原因是类型不匹配:你自己定义的_filelength函数接收的是文件名(char*类型),但调用的时候却传了fileno(hfile)——这是一个文件描述符(int类型),两者完全不兼容,自然没法正确运行。
下面给你几种Linux下用C语言正确获取文件长度的方案,按需选择:
方法1:通过文件描述符获取(对应Windows _filelength的用法)
Windows的_filelength可以接收文件句柄,Linux下对应的可以用fstat(针对文件描述符的系统调用),我们可以改写函数适配文件描述符:
#include <sys/stat.h> #include <unistd.h> #include <stdio.h> long _filelength(int fd) { struct stat st; // 必须检查系统调用的返回值,避免出错场景 if (fstat(fd, &st) == -1) { perror("fstat failed"); return -1; // 返回-1标识错误 } return st.st_size; }
调用方式和你原来的逻辑匹配:
FILE *hfile; long fsize; if ((hfile = fopen("data.arp", "rb")) != NULL) { fsize = _filelength(fileno(hfile)); if (fsize != -1) { printf("文件长度:%ld字节\n", fsize); } fclose(hfile); }
方法2:通过文件名直接获取
如果不需要打开文件,只想通过文件名直接获取长度,可以保留char*参数,但同样要做错误检查:
#include <sys/stat.h> #include <stdio.h> long _filelength(const char *filename) { struct stat st; if (stat(filename, &st) == -1) { perror("stat failed"); return -1; } return st.st_size; }
调用时直接传文件名即可:
long fsize = _filelength("data.arp"); if (fsize != -1) { printf("文件长度:%ld字节\n", fsize); }
方法3:跨平台标准C库实现(fseek + ftell)
如果你需要代码同时兼容Windows和Linux,推荐用标准C库的方法,不依赖系统调用:
#include <stdio.h> long _filelength(FILE *fp) { long original_pos = ftell(fp); if (original_pos == -1) { perror("ftell failed"); return -1; } // 跳转至文件末尾 if (fseek(fp, 0, SEEK_END) == -1) { perror("fseek failed"); return -1; } long size = ftell(fp); // 跳转回原来的位置,避免影响后续文件操作 fseek(fp, original_pos, SEEK_SET); return size; }
调用方式:
FILE *hfile; long fsize; if ((hfile = fopen("data.arp", "rb")) != NULL) { fsize = _filelength(hfile); if (fsize != -1) { printf("文件长度:%ld字节\n", fsize); } fclose(hfile); }
额外注意事项
- 对于超过2GB的大文件,
long类型可能不足以存储长度(32位系统下long是4字节),此时建议改用off_t类型,编译时可以添加-D_FILE_OFFSET_BITS=64参数来启用大文件支持。 - 所有方案都一定要检查返回值!忽略错误检查会导致拿到错误的文件长度,甚至程序崩溃。
内容的提问来源于stack exchange,提问作者user6552697
相关产品推荐
相关产品推荐

