目录
- C语言文件操作指南
- 1. 文件打开与关闭
- 1.1 fopen() 模式参数详解
- 1.2 fclose() 返回值说明
- 2. 文件读写位置控制
-
- 3. 字符级文件操作
- 3.1 fgetc() / fputc() 参数说明
- 4. 行级文件操作
-
- 5. 格式化文件操作
-
- 6. 块级文件操作
- 6.1 fread() / fwrite() 参数解析
- 7. 文件状态与元数据
-
- 8. 其他实用函数
-
- 9. 最佳实践总结
- 9.1 文件操作黄金法则
- 9.2 错误处理规范
- 9.3 性能优化策略
C语言文件操作指南
1. 文件打开与关闭
1.1 fopen() 模式参数详解
模式字符串 | 描述 | 文件存在 | 文件不存在 |
---|
“r” / “rb” | 只读模式 | 打开 | 失败 |
“w” / “wb” | 写入模式(清空内容) | 清空 | 创建 |
“a” / “ab” | 追加模式 | 追加 | 创建 |
“r+” | 可读可写(不截断) | 打开 | 失败 |
“w+” | 可读可写(清空内容) | 清空 | 创建 |
“a+” | 可读可追加(写入时自动定位到文件末尾) | 打开 | 创建 |
安全打开示例:
FILE *fp = fopen("data.dat", "rb+");
if (NULL == fp) {
perror("文件打开失败");
exit(EXIT_FAILURE);
}
1.2 fclose() 返回值说明
返回值 | 含义 | 处理建议 |
---|
0 | 关闭成功 | 无需处理 |
EOF | 关闭失败 | 检查文件是否被其他进程占用 |
2. 文件读写位置控制
2.1 定位函数对比
函数 | 功能 | 典型应用场景 | 注意事项 |
---|
ftell() | 获取当前文件位置 | 记录断点位置 | 返回值类型为long |
fseek() | 设置文件位置 | 随机访问文件 | 二进制/文本模式行为不同 |
rewind() | 重置到文件开头 | 重新读取文件 | 等价于fseek(fp, 0, SEEK_SET) |
文件大小获取技巧:
long get_file_size(FILE *fp) {
fseek(fp, 0L, SEEK_END);
long size = ftell(fp);
rewind(fp);
return size;
}
3. 字符级文件操作
3.1 fgetc() / fputc() 参数说明
函数 | 参数类型 | 返回值 | 典型错误值 |
---|
fgetc() | FILE* | 读取的字符(0-255) | EOF(-1) |
fputc() | int, FILE* | 写入的字符 | EOF |
安全拷贝示例:
int ch;
while ((ch = fgetc(src)) != EOF) {
if (fputc(ch, dest) == EOF) {
perror("写入失败");
break;
}
}
4. 行级文件操作
4.1 fgets() 参数详解
参数 | 作用 | 注意事项 |
---|
str | 存储读取内容的缓冲区 | 必须预先分配内存 |
size | 缓冲区大小 | 包含终止符的空间 |
stream | 文件指针 | 需确保已正确打开 |
安全读取示例:
char buffer[256];
while (fgets(buffer, sizeof(buffer), fp)) {
buffer[strcspn(buffer, "\n")] = '\0';
}
5. 格式化文件操作
5.1 fprintf() 格式说明符
格式符 | 类型 | 示例 |
---|
%d | int | fprintf(fp, “%d”, 42) |
%f | float/double | fprintf(fp, “%.2f”, 3.1415) |
%s | 字符串 | fprintf(fp, “%s”, “Hello”) |
%p | 指针地址 | fprintf(fp, “%p”, ptr) |
结构化数据存储:
typedef struct {
int id;
char name[20];
float score;
} Student;
Student s = {101, "Alice", 95.5};
fprintf(fp, "%04d|%-20s|%05.2f\n", s.id, s.name, s.score);
6. 块级文件操作
6.1 fread() / fwrite() 参数解析
参数 | 说明 | 典型用法 |
---|
ptr | 数据缓冲区地址 | 结构体指针/数组首地址 |
size | 单个元素字节数 | sizeof(DataType) |
nmemb | 元素数量 | 数组长度 |
stream | 文件指针 | 需以二进制模式打开 |
二进制数据存储示例:
#define MAX_ITEMS 100
typedef struct {
int id;
char name[30];
double price;
} Product;
Product inventory[MAX_ITEMS];
size_t items_written = fwrite(inventory, sizeof(Product), MAX_ITEMS, fp);
7. 文件状态与元数据
7.1 stat 结构体关键字段
字段 | 类型 | 描述 |
---|
st_size | off_t | 文件大小(字节) |
st_mode | mode_t | 文件类型和权限 |
st_mtime | time_t | 最后修改时间 |
st_uid | uid_t | 所有者用户ID |
st_gid | gid_t | 所有者组ID |
文件类型判断宏:
S_ISREG(st.st_mode)
S_ISDIR(st.st_mode)
S_ISCHR(st.st_mode)
8. 其他实用函数
8.1 文件管理函数对比
函数 | 功能 | 返回值 | 跨平台性 |
---|
remove() | 删除文件 | 0成功,-1失败 | 通用 |
rename() | 重命名/移动文件 | 0成功,-1失败 | 路径规则不同 |
tmpfile() | 创建临时文件 | FILE指针/NULL | C标准保证 |
9. 最佳实践总结
9.1 文件操作黄金法则
- 始终检查返回值:所有文件操作函数都应检查返回值
- 明确打开模式:根据需求选择正确的模式字符串
- 二进制优先原则:处理非文本数据时使用"b"模式
- 及时关闭文件:使用后立即关闭释放资源
- 缓冲区管理:合理设置缓冲区大小(推荐4K对齐)
9.2 错误处理规范
FILE *fp = fopen("data.dat", "rb");
if (NULL == fp) {
fprintf(stderr, "[错误代码 %d] %s: %s\n",
errno, strerror(errno), "data.dat");
exit(EXIT_FAILURE);
}
if (fclose(fp) == EOF) {
perror("文件关闭失败");
}
9.3 性能优化策略
策略 | 适用场景 | 效果 |
---|
批量读写(fread/fwrite) | 大数据量处理 | 减少系统调用次数 |
内存映射 | 超大文件随机访问 | 避免多次I/O操作 |
缓冲区设置 | 高频小数据操作 | 减少物理写入次数 |
最后提醒:
文件操作是系统编程的基础,遵循以下原则可避免常见问题:
- 使用绝对路径时注意平台差异(Windows/Linux)
- 处理用户输入路径时进行规范化
- 敏感文件操作添加权限检查
- 长期运行程序定期刷新缓冲区(fflush())