这篇文件记录文件描述表。
2 文件描述符表
2.1 什么是文件描述符表
当运行一个程序时,内核会创建进程表task_struct。当open 打开文件后,会在进程表中创建相应的结构体来记录打开的文件,这个结构体就是文件描述符表。
2.2 task_struct 与 文件描述符表 之间的关系
文件描述符表在进程task_struct结构体中。文件描述符表中每个fd对应的都是一个文件表,文件表中存放了文件的读写状态,文件位移量,V节点中存放了文件长度v节点中的i节点信息就是文件属性信息。如下图所示。
- 文件状态标志
文件状态标志,就是open文件时指定的O_RDONLY、O_WRONLY、O_RDWR、O_TRUNC、O_APPEND、O_CREAT、O_EXCL、O_NONBLOCK、O_ASYNC等。比如,fd = open(“./file1.txt”, O_RDWR|O_CREAT|O_EXCL, 0664); open打开文件成功后,会将文件状态标志保存到“文件表”中。 - 文件状态标志作用
读写文件时,会先检查“文件状态标志”,看看有没有操作权限,然后再去操作文件。
比如open时指定的是:open时候创建了文件表和V节点表。
(a)如果打开文件时,指定文件状态标志是O_RDONLY
当写(wrtie)文件时,通过fd检查“文件状态标志位”,发现只允许读,写操作会错误返回,并报“不允许写的错误”。
(b)如果打开文件时,指定文件状态标志是O_WRONLY
当读(read)文件时,通过fd检查“文件状态标志位”,发现只允许写,读操作会错误返回,并报“不允许读的错误”。只有当“文件状态标志”允许相应的操作时,读写操作才能成功进行。 - 文件位移量
文件位移量是文件当前读写位置与文件开始位置的距离。“文件位移量”代表的就是文件读写的位置,read、write读写数据时,通过文件位移量,就知道从哪里开始读写了。一般情况下打开文件时,文件的位移量默认为0,表示读写的位置在文件头上。每读写一个字节,文件读写位置(笔尖)就往后移动一个字节,文件位移量随之+1。调用lseek函数调整文件读写位置,其实就是修改文件位移量。
open时,第三个参数O_APPEND的原理就是基于文件位移量实现的open指定了O_APPEND时,每次写文件时,都会把“文件位移量”设置为“文件的长度”,也就是说写的位置被调整到了末尾,写文件时从文件尾部进行追加。 - 文件长度
在写文件的过程中,每写一个字节的数据到文件中,文件的长度就+1,文件长度也是动态更新的。 - V节点指针
打开文件成功后,当执行read write函数时候,调用不同的函数来实现读写,所以在V节点里面保存了这些不同函数的函数指针,方便调用。 - i节点信息
这个就需要说一下文件的存储了。硬盘分四个区域来存放文件,分别是自举区,超级区,文件属性存储区和文件数据存储区。i节点就在文件属性存储区中。i节点存放在文件属性存储区中,i节点中存放了文件的基本信息,如下图所示。