IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 到底什么是文件描述符??? -> 正文阅读

[C++知识库]到底什么是文件描述符???


在这里插入图片描述

1、文件描述符的引入

1.1 系统调用接口的引入

??不管是学习语言还是学习操作系统,IO流是我们学习过程中不可获取的一个阶段,在这一部分我们会学习打开文件、读写文件等操作,在C语言中我们打开文件调用的是C语言的库函数接口,像fopen打开,fclose关闭,fputs写入,fgets读取,这些都是在C中我们对文件进行操作的一些库函数,但是如果不允许使用库函数接口时我们应该怎么办???
??这时候我们就应该使用系统调用相关接口,我们首先要明确一个概念,C语言接口和操作系统接口是上下级的关系,任何一个语言,不管是C、C++、java、Python都有自己打开文件关闭文件读写文件的库函数,但是这些库函数的使用都是在Linux和Windows系统下进行的,所以任何语言的接口和系统接口是一种上下级的关系。
在这里插入图片描述??在系统调用接口中,我们打开文件使用open、关闭文件close、写入write、读取read。那这些接口和C中库函数接口有什么联系呢?我们可以这样理解:C中调用得这些库函数底层一定封装了系统调用接口,可以认为fopen底层调用open,fclose底层调用close,fread底层调用read,fwrite底层调用write。我们在windows中打开文件,windows底层也有一套自己的windows相关的api系统接口,当我们在windows使用C的库函数时,C调用的就是windows下的系统接口。这样在语言层面上就实现了跨平台性

1.2 文件描述符

??我们查看关于C语言中库函数和系统调用相关接口的使用手册。
在这里插入图片描述
??图中我们给出了C和系统调用的相关接口的使用手册,我们发现C中库函数的类型为FILE*,系统调用接口的类型为int。
??FILE*是文件指针,在C中打开一个文件,打开成功后会返回一个文件指针,该指针指向文件内容的起始地址,文件指针是C语言级别的概念;int fd本质是new file descriptor-文件描述符,文件描述符是系统级别的概念。

2、文件描述符

2.1 演示文件描述符

??光说不练假把式,我们写一份代码来实质性的感受一下文件描述符的概念。

图1 代码
图2 运行结果
??通过上图中,我们就可以观察到了fd的值,但是fd的值为-1,-1意思是这个文件不让我们创建不让我们打开,这是因为单纯的O_WRONLY是没有创建功能的,所以如果你想打开一个文件写入,并且文件不存在想创建的话需要扩加一个选项O_CREAT。
图1 代码
图2 运行结果
??其实OS系统的open接口的O_WRONLY+O_CREAT组合起来就是C语言接口中的w方式,因为他们是上下级的关系,所以fopen一定调用了open,即C语言中的w方式底层同时给open函数传入了两个参数:O_WRONLY+O_CREAT。

2.2 文件描述符的返回值

??刚才我们打开一个文件fd为3,那么我们创建多个是什么情况呢?

图1 代码
图2 运行结果
??我们发现返回值从3开始依次递增,有很强的规律性;而-1代表打开文件失败,那么012在哪呢?又代表什么?

??相信各位读者应该都听过一个概念,C语言程序会默认打开3个输入输出流,其中这三个输入输出流对应的名为stdin,stdout,stderr,文件类型为FILE*,而FILE*是C语言的概念,底层对应的文件描述符,其中stdin对应0,stdout对应1,stderr对应2,换言之012被默认已经打开了,再打开时就是从3开始打开了,所谓的文件描述符,本质其实就是数组下标

2.3 文件描述符底层原理(重点)

??一个进程是可以可以打开多个文件的,无非就是多调用几次open,而我们的计算机中是同时存在大量进程的,而这些进程可能会打开各种各样的文件,所以系统中在任何时刻都可能存在大量已经打开的文件,操作系统的功能之一就是文件管理,就是要对这些打开的文件进行管理。
??而我们都知道,所谓管理就是先描述再管理,底层中描述文件的数据结构叫做struce file,一个文件对应一个struct file,大量的文件就有大量的struct file,我们只需将这些数据结构用双链表连接起来,所以对文件的管理就变成了对双链表的增删改查。而我们现在要做的,这些已经被打开的文件那些文件属于某个特定的进程,就需要建立进程和文件的对应关系。
??每一个进程都有一个task_strut,这个task_struct会指向一个struct files_struct结构体,这个结构体里会有一个指针数组struct file* fd_array[32],而这个指针数组就是文件描述符对应的数组。
在这里插入图片描述
??既然是数组就有下标,下标从0开始依次递增,task_struct结构里会有一个指针变量指向这个struct files_struct结构体,我们这个指针数组中的每个数据都是一个指针变量。默认的3个文件+我们上面的例子中自己打开的log.txt,总共有4个文件描述符打开,这四个打开的文件描述符都对应一个struct file的结构体,结构体里有描述该文件属性的相关信息,而这些struct file文件结构体之间,是通过双链表的形式链接起来的。
??对于输入输出错误,将下标012分配给他们,自己打开的文件从3开始依次分配,当我们将下标和struct file结构体的指向关系表明清楚以后,open函数返回时,就会将下标数字直接返回给调用方,至此在应用层我们就拿到了文件描述符,至此我们就完成了文件和进程的对应关系。所以,所谓的文件描述符实际就是数组的下标
在这里插入图片描述

2.3 文件描述符修饰规则

??文件描述符的分配规则:在files_struct数组当中,找到当前没有被使用的最小的一个下标,作为新的文件描述符。(其实就是将数组从上到下扫描,找没有被使用的)

3、总结

??通过上面的学习,我们知道了文件描述符就是一个小整数,Linux进程默认情况下会有3个缺省打开的文件描述符,分别是标准输入0, 标准输出1, 标准错误2.;0,1,2对应的物理设备一般是:键盘,显示器,显示器。
??而每当我们打开一个新的文件时,系统就会将文件描述符对应的指针数组从上而下进行扫描,找到没有被使用的作为该文件的文件描述符。
在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-30 12:23:34  更:2021-10-30 12:23:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:03:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码