You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

未刷新stdout缓冲区是否会导致文件输出内容错误

结论

是的,如果你注释掉fflush(stdout)代码行,最终HelloWorld.txt中会同时写入Hello World 1和Hello World 2两条内容。

原因说明

首先需要明确两个核心概念的区别:

  • 内核层面维护的文件描述符映射关系:dup2系列函数修改的是这层映射,只会改变后续系统调用写文件时的目标,完全不会操作C标准库在用户空间维护的缓冲区数据
  • C标准库(stdio)层面的用户态输出缓冲区:printf这类stdio函数的输出内容会先暂存在这个缓冲区中,满足刷新条件才会真正调用系统调用写到内核对应的文件里

注释掉fflush(stdout)时的执行流程:

  1. 第一次执行dup2(FILE1,STDOUT_FILENO)后,标准输出对应的底层文件描述符指向原终端输出
  2. 执行printf("Hello World 1\n"),内容写入stdout的用户态缓冲区,此时如果没有触发自动刷新(比如如果标准输出被重定向到文件时默认是全缓冲,就算带换行也不会自动刷新),内容会一直留在缓冲区中
  3. 执行dup2(FILE2,STDOUT_FILENO),修改了内核层面标准输出文件描述符的映射,指向HelloWorld.txt,但用户态缓冲区里的Hello World 1内容没有被清空也没有被写出
  4. 执行printf("Hello World 2\n"),内容追加到同一个stdout缓冲区中
  5. 程序退出时,stdio会自动刷新所有打开的流缓冲区,此时缓冲区里的两条内容会一起写入当前标准输出对应的文件,也就是HelloWorld.txt

保留fflush(stdout)时的执行流程:

fflush(stdout)会把当前缓冲区里的Hello World 1立刻刷入当时对应的底层文件(原终端输出),同时清空缓冲区。后续修改文件描述符后写入的Hello World 2是缓冲区里唯一的内容,程序退出时只会把这一条写入HelloWorld.txt。

对应测试代码

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    int FILE1 = dup(STDOUT_FILENO);
    int FILE2 = open("HelloWorld.txt",O_WRONLY|O_CREAT,0666);


    dup2(FILE1,STDOUT_FILENO);
    printf("Hello World 1\n");

    //THE LINE OF CONCERN
    fflush(stdout);

    dup2(FILE2,STDOUT_FILENO);

    printf("Hello World 2\n");
    close(FILE2);
    close(FILE1);
    return 0;
}

内容的提问来源于stack exchange,提问作者Futuristic Gladiator

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 14:39:02