• 【Linux】认识文件(三):缓冲区


    一.啥是缓冲区?

    缓冲区,官方说法就是:指的是一块用于临时存储数据的内存区域。
    它通常用于数据的输入和输出操作之间,作为数据的中转站,用于平衡输入和输出设备之间的速度差异。

    这么会说肯定不太好理解,所以接下来,就给大伙解开缓冲区的面纱。

    二.缓冲区现象

    #include
    #include
    #include
    #include
    int main()
    {
      const char* message0="hello fwrite\n";
      const char* message2="hello printf\n";
      
      fwrite(message0,strlen(message0),1,stdout);
      //在显示器文件中fwrite message0
      printf("%s",message2);
      //在显示器文件中打印write message1
      fork();
      //创建子进程
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    ./test
    来运行这个程序
    结果如下:在这里插入图片描述

    大伙可能觉得这也没啥

    但是如果我们将结果重定向给文本文件:

    ./test > test.log
    
    • 1

    结果如下:
    在这里插入图片描述

    这里我们能发现这里面
    fwrite和printf被打印了两次

    这里其实就是缓冲区的展现了。

    在这里插入图片描述
    大致情况就是这样了。

    三.缓冲区的刷新方法

    但是这里细心的人可能会有别的疑惑了

    为什么正常运行程序是两条
    在这里插入图片描述
    反而重定向到文件中的时候反而多了两条呢?

    在这里插入图片描述
    这里就要牵扯到缓冲区的刷新方式了:

    缓冲区刷新问题:

    • a无缓冲 ----->直接刷新
    • b:**行缓冲 ----->遇到\n进行刷新 **
    • c:**全缓冲 ----->全部一次性进行刷新 **
    • 进程退出时候会刷新

    要注意:
    一般显示器中的刷新方式是行缓冲
    一般文件的刷新方式是全缓冲

    所以我们这里可以来分析一下了

    输出到显示器:
    在这里插入图片描述
    输出到文件:
    在这里插入图片描述

    这里大伙应该就能明白不同刷新方式的区别的。

    这里没有最好的刷新方式,只有最合适的刷新方式。

    四.缓冲区在哪?

    为什么要问这个问题呢?

    先带大伙来对上面的代码进行小小的改动:

    #include
    #include
    #include
    #include
    int main()
    {
      const char* message0="hello fwrite\n";
      const char* message1="hello write\n";
      const char* message2="hello printf\n";
      
      fwrite(message0,strlen(message0),1,stdout);
      //在显示器文件中fwrite message0
      write(1,message1,strlen(message1));
       //在显示器文件中write message1
      printf("%s",message2);
      //在显示器文件中打印write message1
      fork();
      //创建子进程
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    正常输入到显示器中
    在这里插入图片描述
    结果还是如我们所料

    但是如果输出到文件中呢?

    在这里插入图片描述
    这里我们能发现这里write的官方接口没有被打印两次

    所以我们能猜到:
    write直接就打印了出来,没有进入缓冲区中
    因为子进程会复制缓冲区,如果write进入缓冲区的话
    就会被子进程给复制,从而出现两条write

    这里我们其实就能给出猜想了:
    这个缓冲区只是在C库中,和系统没关系

    其实答案真的如我们所想

    操作系统中其实也会有缓冲区,但是不是我们用户能够管制
    但是C库中的缓冲区是用户级的,我们能够感受到

    一般语言都会有自己的用户级缓冲区,不光是C语言

    这里再来带大伙来验证一下:

    众所周知:
    _exit是系统接口 exit是C库中接口

    所以讲道理,C缓冲区的话,_exit是不会处理的
    但是exit是C接口,所以exit会进行处理。

    这里我们来对比一下:

     #include
     #include
     #include
     int main()
     {
         printf("test");
        _exit(1);                                                                                   
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    结果:
    在这里插入图片描述

     #include
     #include
     #include
     int main()
     {
         printf("test");
        exit(1);                                                                                   
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    结果:在这里插入图片描述结果和我们想的一样

    五.为什么要有缓冲区

    为什么要有这个缓冲区:

    • 提高程序员的效率
      通过将数据传给系统和硬件的工作交给语言
    • 缓冲区的解决输入和输出设备之间的速度不匹配问题
      原理:当数据从一个设备传输到另一个设备时,数据的传输速度可能会有所不同。
      例如,当从硬盘读取大量数据时,硬盘的读取速度相对较慢,而将数据发送到网络或显示器等设备时,速度可能要求更快。为了使这些设备之间的数据传输更加高效,可以使用缓冲区来调节数据的流动
  • 相关阅读:
    Win系统强制删除文件/文件夹
    高频微观结构:日内及隔夜动量因子
    iApp祁天社区UI成品源码 功能齐全的社区应用
    Fiddler基础使用
    c 的网络I/O库总结(libevent,libuv,libev,libeio)
    mfc对话框添加OnMouseMove
    12 - Spring AOP介绍与使用3 - AOP的xml配置文件方式
    【Java】JAVASE面向对象知识点总结
    java八股文易错点(持续更新......)
    基于bootstrap,企业内部管理系统后台框架前端源码,响应式布局
  • 原文地址:https://blog.csdn.net/Ruaaa_iiiiiiiii/article/details/138068167