Linux6.3、IO基础(文件描述符及分析系统接口细节)

文章解释了文件描述符fd的起始值及其与FILE*的关系,揭示了stdin,stdout,stderr与fd0,1,2的关联,以及fd作为内存中文件描述符数组下标的本质。还讨论了系统调用和structfile在文件操作中的作用。
摘要由CSDN通过智能技术生成

个人主页:Lei宝啊 

愿所有美好如期而遇


前言

我们介绍文件描述符的顺序是:

  1. 为什么我们新打开几个文件,open返回值fd从3开始?
  2. fd与FILE*的关系?
  3. fd的理解?

我们就很疑惑,0,1,2哪里去了,为什么fd是从3开始的?

这里我们就要先了解FILE*类型,首先,我们要知道FILE是一个结构体,由C标准库所支持,并且,由此支持了FILE*类型的stdin(标准输入),stdout(标准输出),stderr(标准错误),分别对应着键盘,显示器,显示器。

我们在使用fwrite或者时fputs等文件类函数时,参数通常会有stdin,stdout,我们也应该知道,这些函数他既然能够访问硬件,那么就一定封装了系统调用,就比如fwrite封装了write,fputs封装了read,fopen封装了open,fclose封装了close。

C标准库支持的文件类函数认识FILE*,但我们的系统调用他只认识fd,并不认识FILE*,所以我们上层传入的FILE里必然封装了fd,并且在底层以FILE*->fd的方式传递给了系统调用。(我们使用fopen打开文件,返回值是FILE*类型,fopen的底层封装了open,open的返回值是fd,所以我们也就知道了FILE*类型是封装了fd的,以后其他文件类函数使用时传入FILE*底层就可以得到fd了)

那么现在我们可以揭晓答案了,stdin里封装的fd为0,stdout里封装的fd为1,stderr里封装的fd为2,进程跑起来时这三个文件是被默认打开的,所以我们再打开其他文件,fd就从3开始了。

那么fd是什么呢?

我们从头开始理解,当我们运行一个程序,想让一个进程去访问文件时,如何访问文件?首先是不是应该让文件从磁盘加载进内存中,因为根据冯诺依曼体系,一个文件要被访问执行,首先要加载进内存,然后由CPU去计算执行,那么我们的进程访问文件,只能访问一个吗?当然不是,刚才我们同时打开了多个文件,一个进程默认情况下可以打开1024个文件,那么我们多个进程同时打开多个文件是不是也可以?那么这么多的进程和文件在内存中,进程需要被操作系统管理,文件需不需要?当然需要,怎么管理?同进程一样,先描述,再组织。

也就是说,我们可以通过task_struct中arrry数组,找到所有打开的文件,现在,我们终于可以明白fd本质就是数组下标!它叫做文件描述符。

现在我们重新理解思路,当一个文件打开时,会在内存中创建struct file(包含了磁盘文件的几乎所有内容),之后将他的地址填入数组,给用户(或者说open函数)返回填入位置的下标,当我们想要找到打开的文件时,通过返回的fd就可以找到struct file,而这个结构体几乎包含了文件的所有信息!我们也就能够通过这个结构体访问这个文件,对文件进行一系列操作。

接下来我们验证FILE*对fd的封装

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Lei宝啊

觉得博主写的有用就鼓励一下吧

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

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

打赏作者

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

抵扣说明:

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

余额充值