1. Linux文件编程:深入理解fread/fwrite二进制读写
在Linux系统编程中,文件操作是最基础也是最重要的技能之一。fread和fwrite作为标准C库提供的二进制文件读写函数,相比文本模式读写具有更高的效率和灵活性。我曾在多个嵌入式项目中处理过传感器数据存储,深刻体会到掌握这两个函数的重要性。
二进制文件操作的核心优势在于:
- 直接内存映射:数据在内存中的二进制形式可以直接写入文件,无需格式转换
- 结构体友好:可以整体读写结构体数据,特别适合固定格式的数据记录
- 效率优先:省去了文本解析的开销,尤其适合大数据量场景
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. fread函数详解与应用
2.1 函数原型与参数解析
c复制size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
这个看似简单的函数声明蕴含着几个关键设计思想:
-
双重尺寸控制:通过size和nmemb两个参数,既可以控制单次读取的总量,又可以记录读取的元素个数。这种设计在读取结构体数组时特别有用。
-
缓冲机制:底层采用缓冲I/O,不是每次调用都触发系统调用,这显著提升了频繁小数据量读取的性能。
参数详解:
ptr:数据存储缓冲区。建议预先分配足够空间,否则会导致缓冲区溢出size:单个元素字节数。常用sizeof运算符获取nmemb:请求读取的元素数量stream:文件指针。必须是已打开的二进制文件(带"b"模式)
重要提示:在Linux环境下,"b"模式可以省略,因为Linux不区分文本和二进制模式。但在Windows平台必须明确指定。
2.2 返回值处理的艺术
fread的返回值处理需要特别注意:
c复制size_t ret = fread(buffer, sizeof(struct Student), 10, fp);
if(ret < 10) {
// 处理不完整读取情况
if(feof(fp)) {
printf("到达文件末尾\n");
}
if(ferror(fp)) {
perror("读取错误");
}
}
典型返回值场景:
- 成功读取:返回实际读取的元素个数(可能小于请求值)
- 文件末尾:返回0,需用feof()确认
- 读取错误:返回0,需用ferror()检查
2.3 结构体读写实战
处理学生信息的经典案例:
c复制struct Student {
char name[20];
int age;
int sno;
float score;
};
// 写入示例
struct Student stu = {"张三", 20, 1001, 89.5};
fwrite(&stu, sizeof(struct Student), 1, fp);
// 读取示例
struct Student stu_read;
size_t ret = fread(&stu_read,
