简单说: fwrite 负责“写数据”, fflush 负责“把缓冲里的内容真的推到文件/设备”。
一、 fwrite 做什么?
fwrite 是标准 C 里的带缓冲的文件写入函数,原型:
c
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
它的主要作用:
- 从 ptr 指向的内存中,读取 size * nmemb 字节
- 写入到 FILE *stream 对应的文件流中
- 但不一定立刻写到磁盘或设备,通常是写到缓冲区里
常见特点:
- 写入成功返回实际写入的“元素个数”( nmemb 的数量),而不是字节数
- 出错时返回值小于 nmemb
- 对磁盘文件,一般是全缓冲;对标准输出( stdout ),通常是行缓冲(遇到 \n 才刷新)
示例:
c
FILE *fp = fopen("test.txt", "wb");
int a = 123;
fwrite(&a, sizeof(int), 1, fp); // 写入一个 int 到缓冲区
fclose(fp); // 关闭时会自动刷新缓冲区
二、 fflush 做什么?
fflush 是强制刷新文件流缓冲区的函数,原型:
c
int fflush(FILE *stream);
作用:
- 对输出流/更新流:把缓冲区里还没写出去的数据,立即写到底层文件/设备
- 对 NULL :刷新所有打开的输出流
返回值:
- 成功: 0
- 失败: EOF (并设置 errno )
常见用途:
- 在 fwrite 之后、但还不想 fclose 时,确保数据真的写到文件
- 多进程/多线程同时写同一个文件时,控制何时把缓冲数据落盘
- 调试时,避免因为缓冲导致“明明写了但看不到”的情况
示例:
c
FILE *fp = fopen("test.txt", "wb");
fwrite("hello", 1, 5, fp);
fflush(fp); // 强制把缓冲区内容写入文件
// 之后即使程序崩溃,数据大概率已经在文件里
三、 fwrite 和 fflush 的关系与常见坑
1. 关系
- fwrite :把数据从用户内存 → C 库缓冲区
- fflush :把数据从 C 库缓冲区 → 内核缓冲区 → (视系统而定)磁盘
缓冲区满、 fclose 、正常程序退出时,C 库会自动调用类似 fflush 的逻辑,所以很多时候你不手动 fflush 也能看到文件内容。
2. 常见坑
- 只 fwrite 不 fflush ,程序异常退出(崩溃、信号),缓冲区里的数据会丢失
- stdout 是行缓冲,用 printf 但没 \n ,又没 fflush(stdout) ,可能看不到输出
- fflush 对输入流(只读打开的文件)行为是未定义的,不要这么用
示例:
printf("hello"); // 可能不会立刻输出,因为没 '\n'
fflush(stdout); // 现在才保证输出到终端
简单总结: fwrite 是“写到缓冲区”, fflush 是“把缓冲区里的内容立刻写出去”。