【Linux基础IO】深入理解缓冲区

缓冲区在文件操作的过程中是比较重要的,理解缓冲区向文件刷新内容的原理可以更好的帮助我们更深层的理解操作系统内核对文件的操作。

FILE

因为IO相关函数与系统调用接口对应,并且库函数封装系统调用,所以本质上,访问文件都是通过文件描述符fd访问的。所以C库当中的FILE结构体内部必定封装了文件描述符fd。

bff8a8624f4543188f72a787a76fbbbf.png

缓冲区分析

2943da57885e41e1a3d6ba3297973942.png

刷新方式

刷新指的是:将用户级缓冲区里的内容刷新到内核级缓冲区里。

1.无缓冲 ----- 直接刷新

2.行缓冲 ----- 遇到\n刷新(向显示器文件写入内容)

3.全缓冲 ----- 用户级缓冲区满了才刷新(向普通文件里写入内容)

进程退出时也会刷新

 向显示器文件写入内容的过程:

当我们调用对文件写操作c库函数(printf、fprintf,fwrite)向显示器文件写入内容,首先是将内容写到FILE的c提供的缓冲区里,刷新方式采取2.遇到\n刷新,我们调用的c库函数就会调用它封装的write,write根据FILE里的fd在内核中找到对应的文件结构体对象里指针指向的缓冲区里;当我们调用系统调用write时,write将内容直接写到被写入文件结构体对应的内核缓冲区里,然后由操作系统将内容传送到磁盘。

#include <stdio.h>
#include <unistd.h>
#include <string.h>
  int main()
  {
    const char* str ="linux";
    const char* str1 = "OS";
    //库函数
    fprintf(stdout, "hello");
    fwrite(str, strlen(str), 1, stdout);
    //系统调用
    write(1, str1, strlen(str1));                                                                                                                        
    close(1);                                                                                                                                
    return 0;                                                                                                                                
  }

4155da52c50b4030a0e6419cc03b0f82.png

 可以看到close了fd=1的文件(即显示器文件),库函数fprintf、fwrite函数和系统调用write里的要向显示器文件输入的字符串末尾都无\n,但是为什么只有系统调用向显示器文件成功写入了字符串呢?这是因为c库对文件操作函数内部提供了缓冲区。另外,我们这里所说的缓冲区, 都是用户级缓冲区。write系统调用将要写入显示器文件的内容直接写到内核级缓冲区,因此可以打印出write写入的内容;c库函数由于要等到进程退出才可以将内容从用户级缓冲区刷新到内核级缓冲区,但在进程退出前,调用了close(1),关闭了显示器文件,因此显示器文件结构体对应的内核级缓冲区被关闭了,无法向里面刷新内容,也就无法将内容写入到磁盘里的显示器文件。如果要写入的字符串末尾都加了\n(刷新方式为)那么就全部会被写入到显示器文件里,并由显示器打印出来。

2f132490329d4dfbb842f78643479d4f.png

向普通文件写入内容的过程:

过程和向显示器文件写入内容一样,刷新方式采取3.全缓冲。

#include <stdio.h>
#include <unistd.h>
#include <string.h>
  int main()
  {
    const char* str ="linux";
    const char* str1 = "OS";
    //库函数
    fprintf(stdout, "hello");
    fwrite(str, strlen(str), 1, stdout);
    //系统调用
    write(1, str1, strlen(str1));                                                                                                                        
    fork();                                                                                                                                
    return 0;                                                                                                                                
  }

f8623a0f44ca4bc8968fcf2d618aa55d.png

为什么c库函数写入的内容写入到text.txt了两遍?

调用库函数向文件text.txt写入文件时刷新方式为3.全缓冲,也就是说只有进程退出时才可以刷新,因为fork()创建了子进程,向内核缓冲区刷新内容时,子进程的内核缓冲区内存空间发生写时拷贝。

  • 18
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值