【文件fd】文件描述符fd | 文件描述表

目录

1.文件描述符fd

2.系统调用的0/1/2

3.C语言的stdin/stdout/stderr

4.系统调用的0/1/2和C语言的stdin/stout/stderr二者的关系❓

5.文件描述表

5.1 文件描述符概念

5.3 文件对象strcut file

5.4 进程和文件对应关系

5.5 文件描述符理解

5.6 源码查看 


1.文件描述符fd

  • open系统调用的返回值是一个整数fd。
  • 成功创建一个新的文件描述符(整数),失败就-1和错误码被设置。
  • man open
  • /return val

2.系统调用的0/1/2

  • open返回值这个整数是什么❓
  • 查看下文件描述符☞形成了文件,打印的文件描述符是3/4/5/6
  • open的返回值是3/4/5/6,为什么呢❓正常情况下,打开失败,返回值是<= -1的,怎么不见0/1/2呢❓
  • 我们自己的打开普通文件描述符是从3/4/5/6开始,可见0/1/2是已经被打开且占用了。
  • 0/1/2是系统启动时自动默认给我们打开得三个设备文件。
  • 0:标准输入,键盘。
  • 1:标准输出,显示器。
  • 2:标准错误,显示器。

3.C语言的stdin/stdout/stderr

  • 在C语言当中,也默认自动会打开三个输入输出文件流。(FILE*类型的文件流)它们三个所对应的类型都是FILE*类型。
  • C语言中的fopen文件打开操作中的返回值类型是一样的☞FILE*类型。
  • man 3 fopen
  • man 3 stdin
  • man 3 fprintf
  • extern FILE *stdin;
  • extern FILE *stdout;
  • extern FILE *stderr;
  • C语言中也可以使用fpirnt来打印(传参是文件流FILE*类型),不仅仅可以使用printf。
  • 数据刷新,也可以使用stdout文件流。

4.系统调用的0/1/2和C语言的stdin/stout/stderr二者的关系❓

  • 无论是在linux当中还是C语言当中,都是把键盘/显示器等当成文件来看待的。
  • 如果想要对键盘/显示器进行操作。可以使用C语言中的stdin,stdout等(fprintf),也可以使用系统调用中中的0/1/2(write)。
  • 系统会给我们打开三个设备文件,C语言也会默认给我们打开三个文件流。
  • 系统和语言二者存在怎样的关系呢❓
  • ❓我们并不知道C语言如何使三个文件流打开,一定是类似fopen的接口。

5.文件描述表

5.1 文件描述符概念

  • 系统调用:1:标准输出,显示器。(为例)
  • 系统调用接口write向指定的文件描述符(数字fd)写入,就是往一个指定的文件写入。
  • 类似使用C语言的printf 和 fprintf 往stdout 打印数据。直接使用系统调用接口,往显示器文件所代表的文件描述符1打印。
  • 显示器文件设备不用打开,是程序启动时默认打开的。
  • man 2 write
  • 像正常合法的0123456的连续的小整数被称为 文件描述符

  • ❓怎么理解write向一个整数里面写入,就相当于向文件里面写呢。

  • ❓fd的本质是什么

5.3 文件对象strcut file

  • 系统调用是OS给用户提供的接口。程序运行起来,才能把文件打开,才能文件操作。
  • 研究打开文件(文件操作)本质是:研究进程和文件的关系。
  • 程序必须启动起来,成为在OS中的进程,执行到open打开文件代码,文件才被打开。
  • 一个进程可以打开多个文件,OS当中有很多进程,对应打开很多文件。
  • OS当中一定会存在非常多的被打开的文件。(没有打开的文件在磁盘中),OS对内核中被打开的文件,必须要管理❗
  • 管理:先描述再组织
  • 描述:OS必须为被打开的文件,创建对应的内核数据结构struct file ☞源码
  • struct file一般都包含的是文件的属性(权限/打开方式/标记位等等)
  • 组织:OS会创建非常多的struct file内核数据结构,同时把每个被打开文件的struct file以双链表的形式联系起来。形成双链表。OS对文件的管理,转化成为对双链表的增删查改。

strcut file

  • struct file 里面会包含一个指针,指针指向一段 系统与该文件对应的内核级的缓存(OS给每个被打开的文件申请的一段内存)
  • 文件=内容+属性
  • 使用磁盘文件的属性 初始化 在OS中被打开的文件的struct file
  • 使用磁盘文件的内容 加载 在OS中被打开的文件的内核级缓存中(想读直接读,想写就写入,最后再刷新到磁盘即可)

5.4 进程和文件对应关系

  • OS存在很多进程task_struct,也存在很多被打开的文件struct file❓哪个进程对应哪个被打开的文件。
  • OS是把所有打开文件管理在一起的
  • 进程 : 文件 = 1:n
  • 一定要能表征进程和它打开文件之间的对应关系。OS必须建立进程和文件的关系。

  • OS在进程PCB(task_struct)中存在一个属性指针struct files_struct *files
  • 结构体对象 struct files_struct 是一种数据结构
  • 在struct files_struct结构体内部存在 一个指针数组 struct file* fd_arry[N] 
  • 指针数组就存在数组的下表:0/1/2.....
  • 指针数组 struct file* fd_arry[N] 的每个数组下表对应的数组元素(指针)指向文件结构体对象  struct file
  • 进程和对应打开的文件建立联系:只需要把描述该文件的 结构体变量 的地址填入指针数组即可
  • 文件描述符fd本质:内核的进程和文件映射关系的数据下标❗
  • 以上看☞源码证明

综上所述:一个进程想要找到对应被打开的文件,只需要把该文件 对应的 指针数组元素的下标拿到手即可。返回这个指针数组的下标给上层用户,拿到下标就可以对这个文件进行文件操作。

5.5 文件描述符理解

  • 文件描述符fd本质:内核的进程和文件映射关系的数据下标❗
  • man 2 open
  • man 2 write
  • man 2 read
  • man 2 close

写的流程

  • 首先通过open拿到文件描述符(下标),使用write/close/read等系统调用接口文件操作。
  • 在使用系统调用接口的时候,都必须传入fd参数。
  • OS拿到fd,就知道用户要访问当前进程的哪个下标了,就根据下标找到文件。
  • 把用户级缓冲区的数据,拷贝到对应文件的内核级缓存当中。
  • 最后由OS定时刷新到外设磁盘当中,完成一次文件的写入。

5.6 源码查看 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

唐唐思

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

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

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

打赏作者

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

抵扣说明:

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

余额充值