在基础IO中,我们所讲的都是对被打开文件的管理,但是不是所有的文件都是被打开的,对那些在磁盘中保存的没有被打开的文件,我们同样也需要管理,这个就像是快递站中等待被人取走的快递,我们需要将它们分门别类管理起来,方便别人来取,同理,我们也需要对磁盘上的文件进行管理,方便在访问文件时快速定位文件
所以文件的管理工作分为两个部分:1、打开的文件 2、没有被打开的文件。这就是文件系统需要做的工作,主要是关于文件存储(文件 = 内容 + 属性)
一、磁盘---硬件---物理存储结构
二、磁盘存储的逻辑结构
上面的磁盘是硬件对文件的存储,但我们操作系统要管理硬件还需要先描述在组织。我们可以把磁盘的存储空间抽象成一个数组,具体如下
根据上面说的,我们知道对磁盘空间的管理可以转换成为对数组的管理,但是我们具体是如何管理的呢?在装系统的时候,我们将电脑的空间划分为C盘、D盘、E盘等进行使用,也就是说我们要将管理的空间变小,这样方便管理,所以我们做了下面的操作
通过上面这张图,我们大致了解了文件管理的工作细节,但是有一个问题,Linux识别和对文件的管理只通过inode编号,而我们用户从来不用inode编号,用的都是文件名, 所以两者必然具有映射关系,那么这对关系存放在哪里呢?
再次理解目录
- 目录的内容是什么?目录内部直接保存文件的文件名和inode的映射关系。两者互为键值。所以一个目录中不能存在同名的文件
- 在一个目录下,新建,删除,修改一个文件需要什么权限?w,因为需要改变文件名和inode的映射关系,即修改目录内容
- 文件名不属于文件的属性,它只存放在目录中
如何找到一个文件?
我们只要找到该文件所在的目录,然后通过文件名得到与它对应的inode编号,然后就可以找到该文件,这很容易理解,但问题是我们如何找到文件所在的目录?我们知道目录也是文件,所以我们只要不断重复上诉操作,就能得到一个路径,从而找到我们需要的文件,那么这个路径我们如何得到呢?
pwd命令我们都用过,它能打印当前所在的路径,其实本质就是进程本身会记录程序所在的路径。而我们打开文件的操作其实都是交给进程去完成的,所以我们能找到文件。
当然对于那些高频访问的文件,文件的路径会被放在缓存里,方便以后找到文件,同时操作系统中有一个dentry结构体用来记录路径,有兴趣可以去自行了解一下
但是还有一个问题,前面说找到路径就能找到文件,而路径是由一个个目录文件组成,也就是一个个inode编号组成的,而inode编号只在分区内是唯一的,那么我们一开始如何判断这串路径属于哪个分区呢???
一个磁盘,被分区格式化之后,Linux中要使用这个分区,要把这个分区要进行挂载mount,简单来说就是将分区和目录建立映射关系,所以路径起始位置的目录就已经确定了文件在哪个分区。
三、软硬链接
由上图可知:软链接是一个独立的文件,硬链接不是,因为它没有独立的inode编号
- 什么是软链接?它是一个独立的文件,有独立的inode,里面存放的是它链接的文件的路径,类似于windows中的桌面快捷方式,能在其他的目录下打开或执行链接文件
- 什么是硬链接? 它不是一个独立的文件,它的inode和链接文件相同,这就说明两者对应同一个文件,也就是说它只是在指定目录内部对某一个inode(文件)建立的另一个映射关系,本质test2和test2.hard.link是同一个文件的不同名称。
为什么创建普通文件的硬链接数为1,创建目录的硬链接数却是2呢?
肯定是有两个不同的文件名指目录文件inode编号
如果我们在newfile中再创建一个文件呢?
硬链接数变成了3,原因在于新建的文件里也存在newfile的硬链接
所以目录中的两个隐藏文件./..是当前目录和上级目录的硬链接,
同时,文件系统是否删除一个文件,就是看该文件的inode对应的文件名是否为0(即硬链接数),所以inode结构体中还有一个引用计数用来记录有多少个文件名指向该inode,如果引用计数变为0,就删除该文件
注意:不允许对目录建立硬链接