本文目标:
⭐理解文件系统中inode的概念
⭐认识软硬链接,对比区别
文件操作的本质是进程与被打开的文件之间的关系。那么没有被打开的文件怎么办?OS如何去管理它们?没有被打开的文件,安安静静地在磁盘里面放着,磁盘中存在大量的文件,这些没有被打开的文件,被OS静态管理起来,方便随时打开。管理被打开文件,叫做文件系统,虚拟文件系统,管理没有被打开的文件,也称为文件系统,躺着的文件系统。
要理解文件系统,我们需要了解清楚,磁盘是如何存储文件的。
磁盘
首先需要了解磁盘的结构,下面我们将展开三部分来讲:即磁盘的物理结构、磁盘的存储结构和磁盘的逻辑结构。
磁盘的物理结构:
磁盘是我们计算机中唯一一个机械结构的,再加上它是外设的原因,因此磁盘的访问速度很慢(相较于计算机其它硬件)。每个磁盘有若干个盘片,每个盘片有两盘面。
需要注意的是:磁头在盘面上来回摆动,磁头跟盘面是没有接触的,因为不能刮伤盘面,如果盘面被刮伤了,那么就会遇到蓝屏啊,电脑出问题等等的问题。这也是磁盘不能拆开,需要无尘的原因,也是磁盘需要防止抖动的原因,也是我们的笔记本电脑不要搬来搬去的原因。
物理结构就是这样,简单了解一下。
磁盘的存储结构:
磁盘存储结构如图所示。需要注意的是:①:磁盘的寻址的基本单位是扇区,每个扇区一共512字节 。虽然在一定区域里的若干扇区的长度大小不一样,但是其字节都是512,长度大的存储密度小,长度小的存储密度更大一些。②其中的柱面,其实等价于磁道。③磁头的个数等于盘面个数,并且所有磁头是共进退的。
在每个盘面的上,要定位一个扇区,就要先确认磁道,即要确定对应磁道的哪一个扇区。虽然每一圈磁道的长度不一样,有里到外,长度越大,但是每一条磁道的存储量是一样的,因此每条磁道也会有对应的编址,通过编址就能确认磁道,从而定位扇区。
那么是如何通过编址来确认磁道的呢?答案是磁头的来回摆动,其作用就是来确认磁道。确认磁道后,又该如何定位扇区?答案是盘片在高速旋转的时候,就是让磁头来定位扇区。比如要寻找四号磁道的第2个扇区,那么磁头会摆动到四号的磁道后不动,然后盘片通过旋转,转到指定的扇区。
因此,为了提高效率,当我们要找四号磁道第二个扇区的时候,柱面的存在就是为了提高效率,所有磁头都会指向指定的扇区,而柱面的边界,就是这个扇区的磁道!
综上:想要定位扇区去读取信息,就先确认磁道(Track)或者柱面(cylinder),然后定位磁头(head),最后就能定位到指定扇区(sector)咯。而磁盘中定位任意扇区,所采用的硬件级别的定位方式,叫做CHS定位法。
磁盘的逻辑结构:
磁盘物理上是圆形的,但是我们可以把它想象成是线性结构的。那么,我们就可以从对磁盘的管理,转化成对数组的管理,这也是操作系统在看待磁盘的方法!这种思维方式,就是先描述再组织。
此时,想要找某个扇区,只要知道下标,就可以定位到这个扇区了。这个下标,在OS内部,称为LBA地址(Logic Block Address)(逻辑块地址),又叫线性寻址。下面使用一个例子,用来解析这部分:
设:
盘面:4
磁道/面:10
扇区/磁道:100
扇区:512字节
那么,磁盘的总容量(byte)为:4*10*100*512。每个盘面的下标范围:4*10*100。
接下来的问题是,如果通过LBA来转化成CHS定位法? 如我要找123号磁盘位置
首先需要通过计算,算出需要的盘面、磁道和扇区的位置
①先算出:每个盘面拥有的扇区数:10 * 100 = 1000
②然后算出:123号所在的盘面:123 / 1000 = 0 ----0号盘面。 ---> H
③接着算出:123号所在的磁道:123 / 100 = 1 ---1号磁道。 ----> C
④最后算出:123号所在的扇区:123 % 100 = 23 ---23号扇区。---->S
算出来后,就可以拿着这些地址,去访问磁盘的位置。
操作系统对磁盘进行逻辑抽象的原因:
1.便于管理。
2.不让OS的代码和硬件强耦合,简单来说就是不能让磁盘影响到OS。
虽然磁盘的基本单位是扇区512字节,但是还是很小。因此OS内的文件系统定制了多个扇区的读取,如4KB为基本单位。在这种情况下,哪怕只想读取或修改1bit,也必须讲4KB读取到内存,有必要的话,写回磁盘。那么这样子做,岂不是很浪费内存空间?
这就得提一下局部性原理。局部性原理,意思是说在读取这1bit的数据时,会将这些数据的周围的数据,也会一起读取。因此,必须要担心浪费内存,并且还会提高IO的效率,提高数据命中的效率,是空间换时间的做法!
因此,内存被划分成4KB大小的空间,称为页框。磁盘中的文件,尤其是可执行文件,按照4KB大小分好的块,称为页帧。
块组:
对于计算机来说,不管磁盘的容量分成多少块,每块的容量相同也好,不相同也好,都是二进制的形式,因此只需要管理好一块分区,就能管理好剩余的分区。
分区之后,又会在每个区里面分组,此时只要有办法能管好一组,那么其它组也就能管好了,也就能把整个区管好了,从而能把整个磁盘管好了,采用的是分治思想。
Boot Block:启动块
Super Block(超级块):比如我们分出一块区,D盘之类的,然后进行格式化,格式化的本质就是写入文件系统,那么文件系统的信息就会保存在SB当中,包括这个分区一共有多少组?起始块号是多少,结束块号是多少,每一个分组从哪开始从哪结束,每一个分组已经被使用了多少,没有被使用的又是多少,使用率的多少,整个分区的健康状态如何,文件系统操作的方法等等信息。
对于超级块来说,我们看上图,注意到它是在0号分区里的,而SB那么重要,但是却不是在整个区里面,而是在0号区里面,其实每一块区每一块分组都有,当然也可以没有,但是是多块拥有的,其作用是备份。当我们的超级块不小心丢失,可以从别分组里面拷贝一份,文件恢复。
ionde:对于文件,文件 = 内容 + 属性。在Linux中,文件的内容和属性是分批存储的!而保存文件的属性,是一块叫做inode的块。inode的大小或128byte或256byte,一个文件一个inode,inode几乎包含了文件的所有属性,但文件名并不在inode里面。
Data blocks: 保存文件内容的是一块叫做Data blocks的块,它的大小是随着应用类型的大小变化而变化,比如一张图片的大小,一部电影的大小,一份源码的大小。
因为一个文件一个inode(当然,并不是所有文件都有自己的inode,这里先不讨论),那么inode为了分辨出彼此,都会有自己的一个ID,如下图:
而在分组里面的inode Table就保存了分组内部所有可用的inode,Data Blocks保存了分组内部所有文件的数据块。也就说,文件的属性就放在了inode Table里面的某个inode中,而内容就放在了Data Blocks里面的某一块或多块没有被使用的数据块当中。因此,我们需要一个功能,用来查找这两块哪个inode或数据块没有被使用过的。所以就拥有了inode Bitmap。
inode Bitmap:保存了inode对应的位图结构。
Block Bitmap:保存了数据块对应的位图结构。
位图:假设有一千个inode,那么我们就需要一千个bit来表示inode的状态。比如0101这四个bit,假如表示的是前四个inode,那么1就表示这个inode被使用了,0就表示这个inode没有被使用,而位图就用来表示这一千个bit,位图中的比特位是跟当前文件的inode的位置是一一对应的,可以用来判断inode的状态。
Group Descriptor Table:简称GDT,叫做块组描述表。用于保存对应的分组的宏观属性,比如有多少个inode,多少个数据块等等
所以,当我们要查一个inode的时候,就是找它的编号,这是在查找它对应的文件的属性。那么查找文件的内容呢?那么多块数据块,一个文件的内容,可能就要保存在若干个数据块里面。
其实每个inode,都是一个结构体,里面存着文件的属性,比如indoe的编号、文件的大小等等属性,其中有一个属性是记录数据块的数组,通过这个数组能够找到对应的数据块。 同时,为了节省空间,一般从下标为12的开始,所指向的数据块里面,也包含了另外的数据块的id,这样就能大范围地包含住所有所需的数据块。
以上的操作是创建文件,添加文件,那删的话,该如何操作?
其实很简单,就是将位于inode Bitmap中的位图对应的inode比特位和Blocks Bitmap中的位图对应的数据块比特位,从1置为0,文件就删除了!
但是问题是,我们平时使用文件时,并不是用文件的inode啊,而是文件名。
文件一定是在某个目录下,根目录也是目录,而目录也是文件!是文件,就有块,有组,有块组,那就有自己的inode和数据块,inode放的是目录文件直接的编号,而数据块放的是当前目录下的文件名和各自的inode的映射关系!
因此,当我们创建一个文件的时候,一定是往根目录的数据块里面写入文件名跟其映射的inode关系,也就必须有写入权限,当要罗列文件的时候,就必须要有读权限,要访问根目录的数据块!
软硬连接
先来看看软链接和硬链接的文件:
软链接,使用:
ln -s 文件名 软链接的名字 -s表示就是soft的意思
此时创建了一个软链接的文件,可以看到此时两个文件均是独立文件
创建硬链接:
ln 文件名 硬链接的名字
软硬链接的区别:
区别在于是否具有独立的inode!有独立的inode,就可以当作独立文件来看待。从上面的结果来看,inode的编号,软链接的inode跟其它两个都不一样。因此软连接拥有独立的inode,是独立文件,而硬链接没有,那么建立一个硬链接,到底有什么用?
如果我们对没有软硬链接的普通文件进行操作,写一些内容进去,就会发现,普通文件的大小变大了,同时硬链接的也变大了!并且可以注意到,硬链接的文件属性跟普通文件属性是一模一样的!
可以从侧面看出,“hello Linux”已经同时被写入到了两个文件里面区了,这里就不展示出来了。
因此我们知道了,创建硬链接,根本就没有创建出新文件,因此,硬链接的inode和数据块,用的都是别人的,也就是那个所谓的普通文件的。由此看来,硬链接其实就是在当前目录下,新增文件名和inode的映射关系,映射普通文件!在inode中,有一个引用计数,称作硬链接数,用来记录有多少人指向它。这也是为什么我们看到普通文件和硬链接文件的属性里,有个2,而软链接是的1,那个就是硬链接数。
此时如果将普通文件,也就是没有软硬链接的那个删掉,此时,硬链接的文件并不会消失,只是硬链接数从2变成1。所有,真正地把文件删除,是当这个文件的硬链接数变成0的时候,才算真正被删除,因此硬链接的作用就是硬链接重要的文件,防止误删,而且还可以以.开头,隐藏起来。
此时,这个留下来的硬链接的文件,不就相当于原本的文件进行了重命名吗!但是硬链接并不是为了重命名而存在的,而是防止误删。
此时的软链接文件,还是存在的,因为它是一个独立文件嘛,但是它失效了!因为软链接的文件用的是原本文件的文件名,原本的文件被删了,它就找不到这个文件名了,一删它就找不到,这就说明软链接拥有查找原本文件的方式!在一个树状结构当中,我们查找一个文件的方法是根据路径来查找的,而软链接的文件,它的数据块里面保存的是原本的文件,也就是目标文件的路径!而这个文件已经被删除了,路径没了,因此软链接也就失效了!
综上:软链接相当于Windows下的快捷方式,软链接可以找到目标文件,快捷方式也是目标文件的打开方式之一。
软硬链接的作用:
软链接类似快捷方式,那么比如我们在根目录里面写了一段C程序,然后要在另外的目录去执行,一般情况下在输入执行指令的时候,要输入路径,但如果我们在这个目录里面创建这个C程序的软链接,那么就可以不需要输入目录, 就好比如我的QQ在C盘的某个文件夹里,我在桌面的这个目录文件里创建了QQ的快捷方式一样。
对于硬链接,我们发现,在没有硬链接之前,普通文件的硬链接数一开始就是1,因为普通文件,本身就有自己的文件名和inode的映射关系,所以在inode里面的计数器就会是1,也就是硬链接数。如果创建一个目录,一个空目录,它一开始的硬链接数是2,这是为什么呢?
因为空目录本身就是一个文件,然后每个目录里面,都有两个隐藏目录,其中的一个叫做当前目录".",这个目录就是当前目录的硬链接!因此它的inode编号跟空目录本身是一模一样的,所以有两个硬链接数。
还有一个现象就是,当我们在这个空目录empty里面,创建一个空目录dir,此时就会发现,empty这个空目录的硬链接数变成3了。原因很简单,dir里面也有两个隐藏目录,一个是dir自己的硬链接,另外一个是上一级目录的硬链接!这就是cd ..是返回上级目录的原因,这个".."就是上级目录的硬链接!所以,此时的empty目录,一共有两个硬链接,包括自己一个,一共3个硬链接数!
温馨提示:
硬链接:①Linux不允许普通用户给目录创建硬链接。②不能在不同的文件系统下创建硬链接,即普通文件和硬链接的文件需要在同一个文件系统下。③不能对不存在的文件进行硬链接。
软链接:①可以给目录创建软链接。②可以跨文件相同。③可以对不存在的文件进行软链接,因为对于软链接指向的目标文件,是一个字符串。
ACM:
ACM即:Access 最后访问时间、Modify 文件内容最后修改时间和Change 属性最后修改时间。
温馨提示:修改了文件属性,只有Change的时间更改,而修改了文件内容,Modify和Change都会更改,因为大小变了即属性变了。对于Access,如果在短时间内频繁访问,那么这个时间是不会更改的,只有在一段时间内访问了,才会被修改。
⭐⭐⭐文件系统相关内容讲解完毕,那么接下来就是关于动静态库的学习咯,加油!⭐⭐⭐
下一篇预告:动静态库!