一个进程可以打开/创建多个文件,即 进程:打开的文件 = 1:n
OS中存在多个进程,那就说明可能存在更多文件
所以,OS必须对进程中打开的文件进行管理
在了解文件如何被管理之前,我们需要先了解 文件是以何种形式存在于操作系统上的??
目录
一、文件的存储方式
1、文件的一般存储形式
2、文件的数据化存储形式
二、进程与struct file的关系
三、文件描述符是什么?
四、文件结构体struct file如何跟底层驱动打交道?
五、总结:文件读写的过程
(1) 打开某个文件,获取对应的文件描述符
(2) 根据文件描述符定位到对应的文件结构体的具体位置
我们在平时看到的文件诸如下面这样, 但是这只是Windows上表现出来的形式
这是Linux上文件的表现形式,通常这些文件是放在磁盘上的
问:一个空文件(0KB的文件) 是否会占据磁盘空间??
答:会的,无论是Windows还是Linux系统,文件一旦被创建,就会有文件的创建时间、文件权限等属性信息,这些信息都需要地方存放
所以!!!磁盘文件 = 文件内容 + 文件属性
一个文件包含文件内容和文件属性信息,这些信息都会被存放在一个结构体 struct file中
对于多个文件,就以双链表的形式相互联系起来
文件这么多,哪些是属于当前进程的呢??
进程的task_struct中包含一个 struct files来专门管理当前进程的文件(左图)
struct files包含的指针数组 fd_array[ ]存放着各个文件的地址,通过这些地址我们可以找到对应的文件(右图)
数组中存放着 struct file类型的指针,也就是 存放文件信息结构体struct file的地址
每一个地址都能对应到一个文件结构体
下面这篇博客简单解释了文件描述符有什么用?
文件操作——系统调用函数open函数_abs(ln(1+NaN))的博客-CSDN博客C/C++向文件写入,先调用接口函数 ——> 系统调用函数 ——>进入OS ——> 从磁盘中读取文件,这里主要介绍系统调用函数open函数https://blog.csdn.net/challenglistic/article/details/123764901?spm=1001.2014.3001.5501了解了大致用途以后,我们再结合上面的内容,我们就可以知道
每创建一个文件,就会对应一个文件描述符,这个文件描述符很容易让我们联想到数组的下标
没错,上面 指针数组的下标 = 文件描述符,每一个下标都会指向一个文件结构体(可以理解为文件,struct file 是文件数据结构层面的表现)
============================提出问题============================
键盘、显示器、磁盘、网卡等都属于外设,内存和这些外设打交道,无非就是I/O
为了和这些外设打交道,OS提供了系统调用函数read、write函数
(虽然键盘不能写,但是为了统一,键盘的write函数的函数体为空;显示器的read函数也是如此)
============================解决问题============================
这就可能稍微涉及到多态了,一堆子类A、B、C、D继承同一个父类 M,我们可以通过父类对象调用子类的函数
M m = new A();
在上层设计一个总的read/write函数,这样的话我们可以通过改变函数地址来调用不同的函数
所以在文件的结构体中,除了如文件描述符、缓冲区维护指针之外 ,还存放着文件操作函数指针
stdin、stdout、stderr的文件描述符分别是0、1、2
在数据结构层面,每一个文件都有自己的 文件结构体,里面就包含了文件描述符
struct FILE
{
int _fileno; //文件描述符
}
open函数是系统调用函数,只要给出对应的路径,我们就能够获取到这个文件描述符
并进行相应的读/写操作,OS会帮我们去调用对应的驱动函数
char* buffer[1024];
read(fd,buffer,sizeof(buffer));
我们对文件的读写可以先这么理解,因为在写的过程中还涉及到文件缓冲区,在了解了缓冲区以后,我们可以更清楚的了解到这个过程
printf函数打印(二)—— 缓冲区篇_abs(ln(1+NaN))的博客-CSDN博客_printf缓存了解了printf打印的基本流程,但是printf寻文件途中,数据是放在哪呢??https://blog.csdn.net/challenglistic/article/details/124083937