【文件fd】文件描述符的分配规则 | 重定向 | 缓冲区

目录

1.代码现象&问题

1.1关闭fd为0

1.2关闭fd为2

1.3关闭fd为1

2.文件描述符的分配规则

3.重定向 

3.1现象 

3.2解释 

4.缓冲区

4.1现象

4.2解释 


1.代码现象&问题

  • 代码正常,log.txt文件被分配文件描述符fd为3。
  • 关闭fd为0,log.txt文件被分配文件描述符fd为0。
  • 关闭fd为2,log.txt文件被分配文件描述符fd为2。
  • 关闭fd为1,什么都没有打印显示。

1.1关闭fd为0

1.2关闭fd为2

1.3关闭fd为1

2.文件描述符的分配规则

针对0/2的现象❓

  • 文件描述符的分配规则:进程在分配 文件描述符的时候 会查询文件描述符表(内核的文件指针数组)。选择分配最小的没有被使用的文件描述符fd(遍历数组)。

针对1的现象❓1怎么不显示呢❓

  • 依旧遵循上面的分配规则。
  • printf是向stdout打印,stdout里面封装了fd为1。根据文件描述符分配规则,1号文件苗阜已经被分配给了log.txt。所以printf此刻向log.txt打印。

3.重定向 

3.1现象 

系统调用:man 3 write☞直接向1号文件写入

C语言:man 3 printf☞向显示器文件stdout写入☞FLIE类型☞封装的1号文件描述符

无论是printf/fprintf打印都是向stdout打印。(是C语言的库函数只认stdout(fd为1))

FLIE*->stdout->1

本来应该向显示器打印的数据,向文件打印了,这是什么技术❓

3.2解释 

  • 重定向技术:默认往显示器上打印,却打印进了指定的文件。
  • printf和fprintf打印都只认识stdout,是C语言的库函数,只认stdout。
  • stdout所封装的的文件描述符数字fd为1。
  • 根据文件描述符表。首先关闭close(1),再创建打开log.txt文件。明确知道log.txt文件的文件描述符fd为1。在内核文件描述符表中1号下标中的元素指向☞log.txt文件了。
  • printf和fprintf往1号文件打印。也就是往log.txt文件打印。
  • 所谓重定向:改变文件进程的文件描述符表元素(改变指针也就改变指向)

4.缓冲区

4.1现象

去掉fflush刷新,发现log.txt虽然被创建出来了,但是什么内容都没有被写入❓

 

4.2解释 

  • 在C语言层面上struct FILE结构体里面不仅仅封装了文件描述符fd(_fileno)还存在语言级别的文件缓冲区。
  • stdin/stdout/stderr都是一个结构体,都存在各自的语言级别的缓存。
  • ❌使用printf/fprintf并不是直接通过向stdout封装的1号文件描述符向内核级缓存写入。
  • ✔而是通过stdout的语言级别的缓冲区中。
  • C语言把stdout的语言级的缓冲区的内容 通过1号文件描述符 刷新到对应的内核级缓存中
  • fflush(stdout)传参是stdout。是因为是把用户级缓冲区 通过文件描述符拷贝到(刷新)内核级缓冲区,而不是把内核级缓冲区刷新到外设(这是OS定时刷新不管)
  • 正常情况下,不加fflush,进程结束return的时候,会自动冲刷。
  • 所以:因为在return进程结束自动冲刷之前,1号文件已经被close关闭了。数据还未来得及冲刷到内核级缓存中,文件已经被关闭,数据丢失了。
  • 手动刷新:加上fflush或者 自动刷新:不关闭底层的1号文件

 ​​​​​

  • 14
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唐唐思

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值