filelength 是一个非标准的 C 语言库函数,主要用于 Windows 平台,它的作用是获取一个已打开文件的字节大小。

(图片来源网络,侵删)
- 头文件:
<io.h>(在 Windows 环境下) - 函数原型:
long filelength(int handle); - 功能: 获取与
handle(文件句柄)关联的文件的当前长度。 - 重要提示: 由于它不是 C 标准库的一部分,因此在跨平台开发(如 Linux, macOS)中不可用,在标准 C 中,推荐使用
fseek和ftell的组合,或者 C++ 中的std::filesystem。
函数详解
函数原型
#include <io.h> // 必须包含的头文件 long filelength(int handle);
参数
handle: 这是一个整数类型的文件句柄,它不是FILE*指针,这个句柄通常是通过_open()或_sopen()函数打开文件后得到的。
返回值
- 成功: 返回文件的长度,单位是字节,类型是
long。 - 失败: 返回
-1L,并设置errno为错误代码(EBADF,表示无效的文件句柄)。
工作原理
filelength 函数通过底层的操作系统调用(在 Windows 上是 GetFileSize)来获取文件大小,它不会改变文件的当前读写位置。
使用示例
下面是一个完整的 C 语言示例,演示如何使用 filelength,这个示例在 Windows 上的 Visual Studio 或 MinGW �环境中可以编译运行。
#include <stdio.h> // 用于 printf
#include <io.h> // 用于 _open, _close, filelength
#include <fcntl.h> // 用于 _O_RDONLY 等文件打开模式
#include <errno.h> // 用于 errno
#include <tchar.h> // 用于 _tprintf 和 _TCHAR (为了更好的兼容性)
int main() {
// 使用 TCHAR 以便在 Unicode 和多字节字符集之间切换
const _TCHAR* filename = _T("test_file.txt");
int handle; // 文件句柄
long file_len;
// 1. 创建一个测试文件并写入一些内容
// 使用标准 C 的 fopen/fputs 来创建文件,更通用
FILE* f = _tfopen(filename, _T("w"));
if (f == NULL) {
_tprintf(_T("无法创建测试文件 %s\n"), filename);
return 1;
}
_tfputs(_T("Hello, filelength function!\n"), f);
_tfputs(_T("This is a test file.\n"), f);
fclose(f);
_tprintf(_T("已创建测试文件: %s\n"), filename);
// 2. 使用 _open 以二进制只读模式打开文件,获取句柄
handle = _open(filename, _O_RDONLY | _O_BINARY);
if (handle == -1) {
_tprintf(_T("打开文件失败,错误码: %d\n"), errno);
return 1;
}
// 3. 调用 filelength 获取文件长度
file_len = filelength(handle);
if (file_len == -1L) {
_tprintf(_T("获取文件长度失败,错误码: %d\n"), errno);
_close(handle); // 即使失败也要记得关闭句柄
return 1;
}
_tprintf(_T("文件 '%s' 的长度是: %ld 字节\n"), filename, file_len);
// 4. 关闭文件句柄
_close(handle);
// 5. 清理:删除测试文件
_tremove(filename);
_tprintf(_T("已删除测试文件: %s\n"), filename);
return 0;
}
编译和运行
- Visual Studio: 直接创建一个 C++ 控制台项目,将代码粘贴进去即可编译运行。
- MinGW (GCC): 在命令行中编译:
# -lmsvcrt 是链接 MSVC 运行时库,确保 _open 等函数可用 gcc your_file_name.c -o your_program_name.exe -lmsvcrt ./your_program_name.exe
示例输出
已创建测试文件: test_file.txt
文件 'test_file.txt' 的长度是: 39 字节
已删除测试文件: test_file.txt
(注意:不同系统下换行符的长度可能导致文件大小略有差异)
filelength vs. 标准 C 方法
由于 filelength 不是标准的,为了写出可移植的代码,你应该使用标准 C 库的方法,以下是两种最常见的方法。

(图片来源网络,侵删)
fseek 和 ftell (经典方法)
这是最经典、最通用的方法,适用于所有标准 C 环境。
#include <stdio.h>
long get_file_size(FILE* fp) {
long size;
// 1. 保存当前的文件位置
long original_pos = ftell(fp);
if (original_pos == -1L) {
perror("ftell failed");
return -1L;
}
// 2. 将文件指针移动到文件末尾
if (fseek(fp, 0, SEEK_END) != 0) {
perror("fseek failed");
return -1L;
}
// 3. 获取当前位置,这就是文件的大小
size = ftell(fp);
// 4. 将文件指针恢复到原始位置
if (fseek(fp, original_pos, SEEK_SET) != 0) {
perror("fseek (restore) failed");
return -1L;
}
return size;
}
int main() {
FILE* fp = fopen("my_data.txt", "rb"); // "rb" 表示二进制读取
if (fp == NULL) {
perror("fopen failed");
return 1;
}
long size = get_file_size(fp);
if (size != -1L) {
printf("文件大小 (fseek/ftell): %ld 字节\n", size);
}
fclose(fp);
return 0;
}
stat 或 fstat (系统调用方法)
这种方法通过获取文件的状态信息来得到大小,通常比 fseek/ftell 更高效,因为它不涉及移动文件指针。
stat: 通过文件名获取文件信息。fstat: 通过FILE*指针获取文件信息。
#include <stdio.h>
#include <sys/stat.h> // 包含 stat 结构体和相关函数
long get_file_size_stat(const char* filename) {
struct stat file_stat;
// 获取文件状态
if (stat(filename, &file_stat) != 0) {
perror("stat failed");
return -1L;
}
// 返回文件大小 (st_size 成员)
return file_stat.st_size;
}
int main() {
const char* filename = "my_data.txt";
long size = get_file_size_stat(filename);
if (size != -1L) {
printf("文件大小 (stat): %ld 字节\n", size);
}
return 0;
}
总结与对比
| 特性 | filelength |
fseek / ftell |
stat / fstat |
|---|---|---|---|
| 标准性 | 非标准 (仅 Windows) | 标准 C | 标准 POSIX (Linux, macOS, Windows) |
| 平台兼容性 | 仅 Windows | 所有平台 | 所有主流平台 |
| 所需参数 | 文件句柄 (int) |
文件指针 (FILE*) |
文件名 (const char*) 或文件指针 (FILE*) |
| 优点 | 简单直接,底层高效 | 纯标准 C,无需额外头文件(除stdio) | 最高效,不移动文件指针,功能最全 |
| 缺点 | 不可移植 | 需要保存和恢复文件位置,略显繁琐 | 需要包含 <sys/stat.h> |
| 适用场景 | Windows 下的遗留代码或特定项目 | 需要最大可移植性的纯 C 项目 | 推荐!高效、可移植,是获取文件大小的首选方法 |
- 避免使用
filelength:除非你正在维护一个古老的 Windows 专有项目,否则在现代开发中应尽量避免使用它,因为它会破坏代码的可移植性。 - 优先选择
stat/fstat:这是获取文件大小最推荐的方法,因为它高效、标准且功能强大。 - 次选
fseek/ftell:如果你不能使用 POSIX 函数(例如在一些极度受限的嵌入式 C 环境中),fseek/ftell是一个可靠的标准 C 备选方案。

(图片来源网络,侵删)
