文件
当一个进程进行open()系统调用,首先会去系统文件打开表里去查看想要打开的文件是否在里面,如果不在,则会通过文件目录表查找需要打开的文件,若存在,则将文件的目录项复制到系统打开文件表中,包括文件名和索引结点,最后返回一个文件描述符,之后若进程需要继续进行读写等IO操作,则只需这个文件描述符。
所以说不是一个表,文件目录表在外存中,但是也会缓存在内存,以加快目录项的查询。但系统文件打开表一定是在内存中的。
文件描述符
文件描述符(file descriptor)是内核为了高效管理已被打开的文件所创建的索引,其值是一个非负整数(通常是小整数),用于指代被打开的文件,所有执行 I/O 操作的系统调用都通过文件描述符。


一个进程启动时,都会打开3个文件:标准输入、标准输出和标准错误。这3个文件分别对应文件描述符为0,1,2。
内核使用三个相关的数据结构来表示打开的文件:(待确认)
进程级别的文件描述符表:每个进程都有它独立的文件描述符表,他的表项是由进程打开的文件描述符来索引的。每个打开的描述符表项指向 打开文件表中的一个表项。
系统级别的打开文件表:打开文件的集合是由一张打开文件表来表示的,所有进程共享这张表。每个文件表的表项组成(针对我们的目的)包括:当前文件位置、引用计数(即当前指向该表项的描述符表项数),以及一个指向inode表中对应表项的指针。关闭一个描述符(删除一个文件)会减少相应的文件表表项中的引用计数。内核不会删除这个文件表表项,直到它的引用计数为0。
内核对所有打开文件维护的一个进程共享的打开文件描述表,表中存储了处于打开状态文件的相关信息,包括文件类型、访问权限、文件操作函数(file_operations)等。
系统级别的 inode 表:inode 结构体记录了文件相关的信息,包括类型、权限、拥有者、时间、连接数、文件内容所在位置。


对于硬链接来说,只删除一个连接并不影响索引节点本身和其它的连接,只会导致inode中引用计数减1。只有当最后一个链接被删除后,也就是inode中引用计数为0,文件的数据块及目录的连接才会被释放,也就是说,文件才会被真正删除。
对于软链接来说,建立一个软链接,相当于创建一个新的特殊的文件(因为inode号和源文件不同),这个新文件包含了另一个文件的路径名。软链接不会导致原来文件引用计数增加,同时它有自己独立的引用计数。

我们知道文件都有文件名与数据,这在 Linux 上被分成两个部分:用户数据 (user data) 与元数据 (metadata)。用户数据,即文件数据块 (data block),数据块是记录文件真实内容的地方;而元数据则是文件的附加属性,如文件大小、创建时间、所有者等信息。在 Linux 中,元数据中的 inode 号(inode 是文件元数据的一部分但其并不包含文件名,inode 号即索引节点号)才是文件的唯一标识而非文件名。文件名仅是为了方便人们的记忆和使用,系统或程序通过 inode 号寻找正确的文件数据块。图 1.展示了程序通过文件名获取文件内容的过程。 图 1. 通过文件名打开文件
由于硬链接是有着相同 inode 号仅文件名不同的文件,因此硬链接存在以下几点特性:
文件有相同的 inode 及 data block;
只能对已存在的文件进行创建;
不能交叉文件系统进行硬链接的创建;
不能对目录进行创建,只可对文件创建;
删除一个硬链接文件并不影响其他有相同 inode 号的文件。
软链接与硬链接不同,若文件用户数据块中存放的内容是另一文件的路径名的指向,则该文件就是软连接。软链接就是一个普通文件,只是数据块内容有点特殊。软链接有着自己的 inode 号以及用户数据块(见 图 2.)。因此软链接的创建与使用没有类似硬链接的诸多限制,软链接有以下属性:
- 软链接有自己的文件属性及权限等;
- 可对不存在的文件或目录创建软链接;(目标文件不存在则是无效链接)
- 目标文件是相对路径的时候,移动软链接会失效,若是绝对路径则无影响,所以尽量使用绝对路径。
- 软链接可交叉文件系统;
- 软链接可对文件或目录创建;
- 创建软链接时,硬链接计数 i_nlink 不会增加;
- 删除软链接并不影响被指向的文件,但若被指向的原文件被删除,则相关软连接被称为死链接(即 dangling link,若被指向路径文件被重新创建,死链接可恢复为正常的软链接)。
引用计数和硬链接数
每个文件存在两个计数器:i_count 与 i_nlink,即引用计数与硬链接计数。结构体 inode 中的 i_count 用于跟踪文件被访问的数量,而 i_nlink 则是上述使用 ls -l 等命令查看到的文件硬链接数。或者说 i_count 跟踪文件在内存中的情况,而 i_nlink 则是磁盘计数器。当文件被删除时,则 i_nlink 先被设置成 0。文件的这两个计数器使得 Linux 系统升级或程序更新变的容易。系统或程序可在不关闭的情况下(即文件 i_count 不为 0),将新文件以同样的文件名进行替换,新文件有自己的 inode 及 data block,旧文件会在相关进程关闭后被完整的删除。

内核中,对应于每个进程都有一个文件描述符表,表示这个进程打开的所有文件。文件描述表中每一项都是一个指针,指向一个用于描述打开的文件的数据块———file对象,file对象中描述了文件的打开模式,读写位置等重要信息,当进程打开一个文件时,内核就会创建一个新的file对象。需要注意的是,file对象不是专属于某个进程的,不同进程的文件描述符表中的指针可以指向相同的file对象,从而共享这个打开的文件。file对象有引用计数,记录了引用这个对象的文件描述符个数,只有当引用计数为0时,内核才销毁file对象,因此某个进程关闭文件,不影响与之共享同一个file对象的进程.
file对象中包含一个指针,指向dentry对象。dentry对象代表一个独立的文件路径,如果一个文件路径被打开多次,那么会建立多个file对象,但它们都指向同一个dentry对象。
dentry对象中又包含一个指向inode对象的指针。inode对象代表一个独立文件。因为存在硬链接与符号链接,因此不同的dentry对象可以指向相同的inode对象.inode 对象包含了最终对文件进行操作所需的所有信息,如文件系统类型、文件的操作方法、文件的权限、访问日期等。
打开文件后,进程得到的文件描述符实质上就是文件描述符表的下标,内核根据这个下标值去访问相应的文件对象,从而实现对文件的操作。
注意,同一个进程多次打开同一个文件时,内核会创建多个file对象。
当进程使用fork系统调用创建一个子进程后,子进程将继承父进程的文件描述符表,因此在父进程中打开的文件可以在子进程中用同一个描述符访问。

https://blog.csdn.net/giantpoplar/article/details/46955853

文件目录
一个文件对应一个FCB,一个FCB就是一个目录项,多个FCB组成文件目录
索引结点:除了文件名之外的所有信息都存放到索引结点中,每个文件对应一个索引结点。
1、什么是文件目录:一种特殊的文件,是有结构的文件,如上图的表格,用于记录各个文件的属性;最主要的属性是:文件名和物理地址的映射,从而实现按名存取
2、什么是FCB:当你建立一个目录或者文件时,会在文件目录中新增一条记录(记录文件的属性),这样的一条记录就称做一个FCB。
3、FCB中最重要的就是文件名和物理地址的映射,从而实现按名存取。
秋叶依剑