C语言fread函数详解:“工厂传送带”

一句话理解 fread

「fread 就像工厂的传送带,从文件仓库中批量搬运二进制‘货物’到内存卡车,高效且精准!」


函数原型

#include 
size_t fread(void *ptr, size_t size, size_t count, FILE *stream);

入口参数

参数

类型

比喻解释

ptr

void*

内存中的「卡车」(存储数据的缓冲区)

size

size_t

每个「货物单元」的大小(字节)

count

size_t

希望搬运的货物单元数量

stream

FILE*

数据来源的「仓库门」(文件指针)

返回参数

返回值

含义

size_t

实际成功搬运的货物单元数量(≤count)

0

仓库已空或传送故障


核心功能图解

文件内容:■■■■■■■■■■■■■■■■■■■■(20字节)
fread(buffer, 5, 3, file) → 搬运15字节,返回3(成功搬运3个5字节单元)

代码实例:货物搬运实战

场景1:读取结构体数组(学生档案)

#include 

typedef struct {
    char name[20];
    int age;
    float score;
} Student;

int main() {
    FILE *file = fopen("students.dat", "rb");  // 二进制读模式
    if (!file) {
        perror(" 档案库门打不开");
        return 1;
    }

    Student classroom[3];  // 准备3个学生的“卡车”
    size_t loaded = fread(classroom, sizeof(Student), 3, file);

    if (loaded < 3) {
        printf(" 只加载了%zu名学生数据\n", loaded);
        if (feof(file)) printf("(档案已读完)\n");
        if (ferror(file)) perror("(搬运故障)");
    }

    fclose(file);
    return 0;
}

场景2:分块读取大文件(防止内存溢出)

#include 

#define CHUNK_SIZE 4096  // 每次搬运4KB

int main() {
    FILE *video = fopen("movie.mp4", "rb");
    if (!video) return 1;

    unsigned char buffer[CHUNK_SIZE];  // 4KB的“卡车”
    size_t total_read = 0;

    while (!feof(video)) {
        size_t read = fread(buffer, 1, CHUNK_SIZE, video);
        total_read += read;
        // 处理本块数据(如加密/压缩/传输)
    }

    printf("总搬运量:%zu KB\n", total_read / 1024);
    fclose(video);
    return 0;
}

场景3:错误处理(检测文件完整性)

#include 

int verify_file(const char *filename, size_t expected_size) {
    FILE *file = fopen(filename, "rb");
    if (!file) return -1;

    char buffer[1024];
    size_t total = 0;
    while (!feof(file)) {
        size_t read = fread(buffer, 1, sizeof(buffer), file);
        total += read;
    }

    fclose(file);
    return (total == expected_size) ? 0 : 1;  // 验证文件大小
}

技术细节剖析

1. size 和 count 的黄金组合

  • 乘法关系:总读取字节数 = size * count
  • 灵活控制
// 两种等效写法:
fread(buf, 1, 100, file);  // 读100个1字节单元 → 100字节  
fread(buf, 100, 1, file);  // 读1个100字节单元 → 100字节  

2. 返回值隐藏的密码

返回值

含义分析

=count

完美搬运所有单元

<count

文件剩余不足或读取错误

0

文件已结束或严重错误


常见错误与修复

1. 缓冲区溢出(卡车太小)

int data[10];
// 危险!文件可能包含超过40字节数据
fread(data, sizeof(int), 20, file);  // 卡车容量仅40字节,却试图搬运80字节!

修复

int data[20];  // 正确匹配容量
fread(data, sizeof(int), 20, file);

2. 忘记二进制模式(文本文件污染)

FILE *file = fopen("image.jpg", "r");  //  文本模式破坏二进制数据
fread(...);

修复

FILE *file = fopen("image.jpg", "rb"); //  二进制模式

高级技巧:内存映射文件

// 结合fread实现高效数据处理(伪代码)
while (!feof(file)) {
    fread(buffer, 1, CHUNK_SIZE, file);
    process_data(buffer);  // 加密/解密/分析
    upload_to_network(buffer);  // 分块传输
}

总结表格

特性

说明

核心功能

批量读取二进制数据

适用场景

结构体/数组存储、大文件处理

性能

适合块状读取,效率远超逐字节

安全准则

检查返回值,匹配缓冲区大小


总结

  • 像智能传送带:fread 是C语言中处理二进制数据的核心工具,特点:
    1 批量操作:高效搬运数据块,减少IO次数
    2 精准控制:通过 size 和 count 精细调节读取粒度
    3 跨平台兼容:统一处理文本/二进制文件(需正确设置模式)
  • 使用口诀
    「算好尺寸,检查货量;二进制门,必须打开;返回值验,错误不漏!」
原文链接:,转发请注明来源!