程序员求职经验分享与学习资料整理平台

网站首页 > 文章精选 正文

C语言ftell函数详解:“文件坐标记录仪”

balukai 2025-03-26 09:41:54 文章精选 11 ℃

一句话理解 ftell

「精准定位文件‘游标’的坐标位置,告诉你当前在文件的哪个字节‘站点’!」


函数原型

#include   // 必须包含头文件
long ftell(FILE *stream);

入口参数

参数

类型

比喻解释

stream

FILE*

文件的「坐标记录仪」(文件指针)

返回参数

返回值

含义

long

当前游标的位置(字节数,从0开始)

-1L

记录失败(如文件未打开/不支持定位)


核心功能图解

文件内容:A B C D E F G H I J
当前游标在 D 的位置 → ftell 返回 3(第4个字节,从0开始计数)

代码实例1:记录与恢复文件位置

场景:临时跳转读取后回到原位(类似书签功能)

#include 

int main() {
    FILE *file = fopen("data.txt", "rb");  // 二进制模式确保精度
    if (!file) {
        perror(" 地图加载失败");
        return 1;
    }

    // 记录初始坐标
    long initial_pos = ftell(file);
    printf("初始位置:%ld\n", initial_pos);  // 输出0

    // 跳转到第5字节
    fseek(file, 5, SEEK_SET);
    printf("跳转后位置:%ld\n", ftell(file));  // 输出5

    // 读取一个字符
    char c = fgetc(file);
    printf("读取字符:%c\n", c);  // 假设文件内容为"HelloWorld",输出'W'
    printf("读取后位置:%ld\n", ftell(file));  // 输出6

    // 时光倒流:回到初始坐标
    fseek(file, initial_pos, SEEK_SET);
    printf("复位后位置:%ld\n", ftell(file));  // 输出0

    fclose(file);
    return 0;
}

代码实例2:获取文件大小

场景:快速测量文件总长度

#include 

int main() {
    FILE *file = fopen("archive.zip", "rb");
    if (!file) {
        perror(" 包裹无法称重");
        return 1;
    }

    // 跳转到文件末尾
    fseek(file, 0, SEEK_END);
    
    // 记录终点坐标(即文件总字节数)
    long file_size = ftell(file);
    printf("文件大小:%ld 字节\n", file_size);

    // 复位游标
    fseek(file, 0, SEEK_SET);

    fclose(file);
    return 0;
}

技术细节剖析

1.二进制模式 vs 文本模式

  • 在Windows系统中,文本模式会导致坐标计算错误(\r\n会被视为1字节):
FILE *file = fopen("text.txt", "r");  // 文本模式
fseek(file, 0, SEEK_END);
long size = ftell(file);  // 实际值可能小于真实字节数

2.大文件限制

  • ftell 返回 long 类型,最大表示约2GB文件(2^31-1)。
  • 处理大文件需用 fgetpos/fsetpos:
fpos_t pos;
fgetpos(file, &pos);  // 记录位置
fsetpos(file, &pos);  // 恢复位置

3.错误检测

long pos = ftell(file);
if (pos == -1L) {
    perror("坐标记录仪故障");
    exit(1);
}

致命误区

1.未打开文件时调用

FILE *file = NULL;
long pos = ftell(file);  //  程序崩溃!

2.对不可定位的流使用

// 标准输入流不支持定位
long pos = ftell(stdin);  // 返回-1

高级技巧:断点续传

// 记录下载进度
FILE *download = fopen("movie.mp4.part", "rb+");
long resume_pos = 0;

if (download) {
    resume_pos = ftell(download);  // 获取已下载的字节数
    printf("从 %ld 字节处继续下载\n", resume_pos);
} else {
    download = fopen("movie.mp4.part", "wb");
}

对比 fgetpos

特性

ftell

fgetpos

返回值类型

long

fpos_t(结构体)

大文件支持

最大2GB

无限制

可移植性

高(但需用配套函数)


总结

  • 核心功能:精准定位文件游标位置
  • 必用场景:断点续传、文件解析、随机读写
  • 类比记忆:就像快递单号追踪系统,ftell 是查询包裹当前位置的「物流查询器」
最近发表
标签列表