C语言中filelength函数如何正确使用?

99ANYc3cd6
预计阅读时长 19 分钟
位置: 首页 C语言 正文

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

c语言filelength
(图片来源网络,侵删)
  • 头文件: <io.h> (在 Windows 环境下)
  • 函数原型: long filelength(int handle);
  • 功能: 获取与 handle(文件句柄)关联的文件的当前长度。
  • 重要提示: 由于它不是 C 标准库的一部分,因此在跨平台开发(如 Linux, macOS)中不可用,在标准 C 中,推荐使用 fseekftell 的组合,或者 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 库的方法,以下是两种最常见的方法。

c语言filelength
(图片来源网络,侵删)

fseekftell (经典方法)

这是最经典、最通用的方法,适用于所有标准 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;
}

statfstat (系统调用方法)

这种方法通过获取文件的状态信息来得到大小,通常比 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 备选方案。
c语言filelength
(图片来源网络,侵删)
-- 展开阅读全文 --
头像
织梦安装失败?问题出在哪?
« 上一篇 02-28
C语言中system(root)与SYSTEMROOT环境变量有何关联?
下一篇 » 02-28

相关文章

取消
微信二维码
支付宝二维码

目录[+]