文件定位
文件定位函数 fseek、ftell、rewind 控制文件的读写位置。随机访问文件(如数据库文件)需要精确定位,而顺序访问通常不需要。C99 引入 fpos_t 和 fgetpos/fsetpos 支持更复杂的定位需求。
fseek 和 ftell
FILE *fp = fopen("data.txt", "r");
if (fp != NULL) {
/* 移动到文件开头 */
fseek(fp, 0, SEEK_SET);
/* 移动到文件末尾 */
fseek(fp, 0, SEEK_END);
/* 获取当前位置 */
long size = ftell(fp);
printf("File size: %ld\n", size);
/* 从当前位置向后移动 10 字节 */
fseek(fp, 10, SEEK_CUR);
fclose(fp);
}
定位基准
| 基准 | 含义 |
|---|---|
SEEK_SET | 文件开头 |
SEEK_CUR | 当前位置 |
SEEK_END | 文件末尾 |
获取文件大小
long get_file_size(const char *filename)
{
FILE *fp = fopen(filename, "rb");
if (fp == NULL) return -1;
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
fclose(fp);
return size;
}
rewind
FILE *fp = fopen("data.txt", "r");
/* 读取一些内容 */
rewind(fp); /* 回到开头,等价于 fseek(fp, 0, SEEK_SET) */
/* 重新读取 */
fclose(fp);
fgetpos 和 fsetpos
FILE *fp = fopen("data.txt", "r");
fpos_t pos;
/* 保存位置 */
fgetpos(fp, &pos);
/* 读取一些内容 */
/* 恢复位置 */
fsetpos(fp, &pos);
fclose(fp);
fpos_t 可以保存比 long 更复杂的位置信息(如多字节字符状态)。
常见错误
文本模式定位:
FILE *fp = fopen("data.txt", "r");
fseek(fp, 10, SEEK_SET); /* 文本模式下,位置可能不精确 */
/* 需要精确定位时用二进制模式 */
FILE *fp = fopen("data.txt", "rb");
ftell 返回值检查:
long pos = ftell(fp);
if (pos == -1L) { /* 错误 */
perror("ftell");
}
最佳实践
- 随机访问用二进制模式
- 大文件用
fpos_t而非long - 定位后检查返回值
- 需要回到开头时用
rewind - 记录关键位置用于快速跳转