文章目录
- 文件背景知识
- 磁盘文件
- 磁盘物理结构
- 磁盘存储结构
- 对磁盘的存储进行逻辑抽象
- Boot Block
- Super block
- Data blocks
- Inode Table
- BlcokBitmap
- inode Bitmap
- Group Descriptor Table
- 文件名和inode编号
- 创建文件
- 删除文件
- 查找文件
- 软硬链接
- 软链接
- 硬链接
- 查看文件信息stat命令
- 取消软硬链接unlink
文件背景知识
- 在我们平时学习Linux系统的时候,我们都知道在语言级,系统级,Linux一切皆文件,我们所操作的都是被打开的文件
- 其本质上是:一个文件被加载到系统当中,操作系统就把该文件管理起来了。
- 那么我们没有被打开的文件在哪呢?—>磁盘
磁盘文件
- 操作系统作为管理者,硬盘级文件没有被打开,就是由系统在磁盘上统一管理的。
- 单个文件角度:这个文件在哪里,这个文件多大,这个文件的其他属性是什么?
- 在系统角度:一共有多少个文件?各自属性在哪里,如何快速找到,还可以存储多少个文件?如何让快速找到指定的文件等等,对于这一系列问题,可以转化成 如何对磁盘文件进行分门别类的存储,以便更好地进行存储。
磁盘物理结构
-
内存:掉电易失存储介质
-
磁盘:永久性存储介质 (还有SSD,U盘,光盘,磁带等)
-
磁盘是一个外设 + 计算机中唯一的机械设备。磁盘结构:磁盘盘片、磁头、伺服系统、音圈马达……
- 其中,大多数 盘面是多层结构的,两面可读写数据
磁盘存储结构
- 磁盘所采用的是CHS:Cylinder Head Sector的简称,是FDISK在分区期间所需磁盘信息。
-
可以使用CHS定址法来找到一个指定位置的扇区
- 首先找到指定的磁头
- 再找到指定的磁道(柱面)
- 最后定位指定的扇区
-
文件本质上就是在磁盘中占有几个扇区的的问题
对磁盘的存储进行逻辑抽象
-
为什么操作系统要用CHS,耦合度太高,为了方便实现内核磁盘管理
-
磁盘的盘面结构(圆形结构)-> 磁带的线性结构。我们可以将磁盘盘面根据磁带的原理拉伸成一个数组,磁盘的扇区是存储数据的基本单位。
-
操作系统就需要对500G的磁盘进行管理,但是500G的数据量是巨大的,如果整体管理就是低效的。操作系统采取的是分治的方式,对磁盘的管理 -> 对一个小分区的管理。
- 逻辑结构
- 再将这几个区再次进行细分:
- 所以只要管理好一组,就能管理好每一个组
- 此时划分后的每一块叫做块组。每个块组的结构又如下:
- Linux在磁盘上存储文件的时候,将内容和属性是分开存储的
Boot Block
一个分区有一个启动块,开机的属性信息等,每个分区可能存在一份,主要是为了备份,有时候计算机有可能无法成功启动。windows说要不要恢复,也就是可能其中的一个分区的启动块出问题了,恢复也就是找其他分区的启动块,将数据备份一份过去。
Super block
- 超级块(Super Block)是磁盘块组中的一个特殊数据结构,包含了文件系统的元数据信息,让操作系统能够理解和操作文件系统。它记录了文件系统的整体信息,包括文件系统的类型、大小、块位图和inode位图的位置等重要信息。
- 超级块通常是每隔几个分组有一个,它在文件系统格式化时被创建并初始化。超级块记录了文件系统的整体信息,以便操作系统可以理解和操作文件系统。
- Super block相当于是一个文件系统的"总指挥",扮演着一个非常重要的角色.
Data blocks
-
磁盘的基本单位是扇区(512字节),但是操作系统(文件系统)和磁盘进行IO的基本单位是4KB(8*512字节).
-
就算OS想从磁盘中读取一个字节的数据,那么最少也必须读取4KB的数据。至于为什么是4KB,这是经过一些科学的计算最终得出的结论,4KB是最合适的.
-
如果使用512KB,可能会进行更多次数的IO,造成效率降低,而且如果操作系统使用和磁盘一样的大小,万一磁盘基本大小变化了,OS的源代码也需要改变,所以OS有自己一套的规定,这样就完成了软件和硬件的解耦。
-
操作系统与磁盘 IO的基本单位是4KB,这也是一个block大小,所以磁盘也一般叫做块设备。
所以Data blocks可以理解为:
- 1.多个4KB(8*扇区)大小的集合.
linux下文件内容 和 属性是 分开存储的。 - 2.Data blocks里保存的都是特定文件的内容.
Inode Table
inode是一个大小为128字节的空间,保存的是对应特定文件的属性,该块组内,所有文件的inode空间的集合,需要标识唯一性,每一个inode块,都要有一个inode编号。一般而言一个文件,一个inode,一个inode编号。
- 可以使用ls-li来查看inode编号
- 可以简化成下面这张图:
- 相对应的,文件的属性与内容是分开管理的,并且一个块组内的为文件个数也是很多的,因此对于文件的属性与内容我们也需要进行管理。此处的管理方式是位图。
BlcokBitmap
-
回想刚才的data blocks,有那么多的block,我们怎么知道哪一个被占用,哪一个没有被占用呢?
-
这个时候便用到了BlockBitmap,它的内部是一个位图,它的每一个比特位和特定的block是一一对应的,对应的bit位位1, 表示该block已经被占用,否则表示空闲可用。
-
通过块位图,操作系统可以快速了解文件系统上哪些块是可用的,从而进行块的分配和释放。当需要分配一个块给新的文件或目录时,操作系统会查找位图中的空闲位,并将其设置为已分配状态,然后返回该块的地址给请求的进程。
inode Bitmap
-
有那么多的inode,怎么标识哪个被占用,哪个没有被占用呢?还是用inode Bitmap
-
它的内部也是一个位图,每一个比特位和 特定的inode是一一对应的,如果该比特位为1,说明该inode已经被占用,否则表示空闲可用。
-
假设有10000+的inode,那么就有10000+的比特位,分别一一对应,然后用0和1表示未被占用和已占用的两种状态.
Group Descriptor Table
-
Group Descriptor Table(GDT)叫做块组描述符.
-
它用来记录这个块组多大,已经使用了多少,有多少个inode,已经占用了多少,还剩多少,一共有多少个block,使用了多少…等等
-
通过将整个磁盘划分为:大分区 -> 小分区 -> Boot Block + n个块组 -> 块组 -> 6个区域。通过此方式,将快组分割成如此,并且写入相关的管理数据 -> 每一个块组都这么干 -> 整个分区就被写入了文件系统信息(格式化)。
一个文件只能有一个inode,和一个inode编号.
-
我们知道,DataBlocks中是通过每个block存储内容的,那么一个文件 可以有多个block吗?答案是肯定可以的,如果只有一个的话,那么每个文件只能存储4KB大小,这也不切合实际。
-
在文件属性inode中,会有文件的各种属性,其中就包括了一个blocks数组,里面保存了每个block的位置.
-
对于数据量小的文件:
那么如果一个文件特别大,有很多block,blocks数组容不下了,此时如何找到每个block呢?
-
其实我们要知道,一个block块里不仅可以存储文件内容,也可以存储其它块的块号!
-
比如blocks[在文件属性inode中]只有15个元素大小,我们可以前12个对应的block[磁盘结构中]存储文件内容(直接映射),后3个对应的block存储的其它block的位置(间接)。
-
一个block是4KB=4096字节大小,存储一个位置只需要4/8字节(32/64位平台),这样一个block就可以存储1000个其它block的位置,如果还是不够,可以取前997个存储内容,后3个存储block的位置,以此类推…
文件名和inode编号
- 找到文件:先找到文件inode编号 —> 找到分区特定的blcok group —> 找到inode —>相当于知道了属性 —>根据属性便可以找到文件内容.
可问题是我们怎么知道inode编号呢?我们平时用的都是文件名进行操作,比如创建或删除等,所以我们此时需要弄清楚文件名和inode编号之间的关系.
- linux中,inode属性里面,没有文件名这一说法!只根据inode编号辨识文件.
有下面两种场景 :
-
1.在同一个目录下,可以保存很多的文件,但是文件名不能重复.
-
2.目录是文件,也有自己的inode,也有自己的data block,但问题是目录data block里面存储的是什么呢?
虽然说linux下是按inode编号来识别文件的,但是我们看到就是文件名啊,这些文件名也一定是被管理的。
-
这里直接说结论: 目录里的data block 存储的是
inode 编号
和文件名的映射关系
。 -
它们互为key值的,也就是说即可用inode编号做key值,也可以用文件名做key值.
-
这也可以立即为什么创建文件,需要目录有写权限,因为目录保存的是文件名与 inode编号映射关系,只有目录有了写权限,才能将这个映射关系写到磁盘,才能创建成功.
-
回想对于目录的权限操作:
-
进入文件需要x(可执行)权限。
-
创建文件需要w(可写)权限。
- 因为,需要将文件名与inode编号的映射关系写入到目录的data block中。
-
显示文件名与属性需要r(可读) 权限。
- 因为,需要显示文件名,但是文件名存储在目录中,需要文件名就需要在目录中查找;显示文件属性,就需要查找到文件,就需要依托于目录中文件名与inode编号的映射关系。
-
正是因为,查找inode编号是依托于目录结构,所以Linux下查找文件需要绝对路径或相对路径。
创建文件
-
通过我们传入的路径,找到对应的分区、块组,然后在该块组内通过对inode Bitmap的遍历,查找0的同时,使用计数器计算inode编号。以inode Bitmap中0说所对应的位置开辟inode,将属性存储,再根据文件内容,调整其中的black数组(如果没数据清空,有数据根据Black Bitmap分配Data block)。至此文件系统将空间分配,相关数据存储并给出了新建文件的inode编号。再根据该文件处于的目录名,找到目录的inode属性信息,再以属性信息找到目录对应的Data black将用户给予的文件名与文件系统给予的inode标号,存储构建映射。
-
以目录的文件名,找到目录相关数据:Linux内核中会将常用的目录结构构建成一颗树,其内部帮我们构建了文件名与其目录的inode编号的映射关系。本质上:也就是只要你拿到了文件名它的inode,最后就能通过文件目录找到目录的inode,进而找到目录的data block将新建的文件名与其inode标号写进去。
删除文件
- 删除文件,即通过传入文件名,以此找到对应的目录与目录的inode,以此在目录的data black中根据映射关系,找到文件名对应的inode标号,以此找到文件的inode,然后将该文件的inode Bitmap与black Bitmap进行置0。
这也正是:为什么拷贝(下载)文件的时候很慢,而删除文件的时候很快的原因。
-
正是由于拷贝(下载)文件,需要对inode的分配,data block的分配。并覆盖式的一一写入数据。而删除文件只需将标识inode与data block是否有效的Bitmap置0即可。
-
如同通行的路,开辟时需要慢慢建造填补,因为废弃等原因而放弃时只需要一个标识牌即可。需要再次使用时直接铺设就行。
查找文件
-
根据文件名,在其处于的目录的data block中查找到映射的文件inode编号,以此找到文件的inode。
-
当重装操作系统的时候:
-
需要你对磁盘进行分区,就是电脑中的A、B、C……盘。
-
首先需要进行格式化,在磁盘写入文件系统,也就是从哪到哪是一个Block group块的区域的划分、块中的Data block区域划分、inode Table区域的划分、Bitmap区域的划分以及清0、……。(格式化也很简单,就是重写文件系统,清空数据本质上:将Super Bloack、Group Rescriptor Table、两个Bitmap的4个区域全部清0)
-
由于inode是固定的,data block是固定的。所以有时可能出现,其中一个还有空间但是另一个没空间了。于是就会出现系统里还有空间,但是创建文件老是失败的问题。
软硬链接
- 为解决文件的共享使用,Linux 系统引入了两种链接:硬链接 (hard link) 与软链接(又称符号链接,即 soft link 或 symbolic link)。链接为 Linux 系统解决了文件的共享使用,还带来了隐藏文件路径、增加权限安全及节省存储等好处。
创建软链接
ln -s src dest
创建硬链接
ln src dest
- 我们观察到硬链接的
inode
一样,而这里有两个2代表的是引用计数。(一会再说) - 我们观察到软链接,又叫做符号链接,软链接文件相对于源文件来说是一个独立的文件,该文件有自己的
inode
号,但是该文件只包含了源文件的路径名,所以软链接文件的大小要比源文件小。软链接就类似于Windows操作系统当中的快捷方式。
软链接
- 使用快捷方式打印和使用源文件打印都是可以的
- 但是软链接文件只是其源文件的一个标记,当删除了源文件后,链接文件不能独立存在,虽然仍保留文件名,但却不能执行或是查看软链接的内容了。
硬链接
- 通过ls -i -l命令我们可以看到,硬链接文件的inode号与源文件的inode号是相同的,并且硬链接文件的大小与源文件的大小也是相同的,特别注意的是,当创建了一个硬链接文件后,该硬链接文件和源文件的硬链接数都变成了2。
我们删除源文件后,计数变为1了
- 这里面的文件内容还是可以访问,也就是相当于重命名了一下
-
所以硬链接不是一个独立的文件,因为没有独立的
inode
,使用的是目标文件的inode
,在属性列中有一列就是硬链接数 -
文件的磁盘引用计数:有多少个文件名字字符串通过inode指向我就是多少
所以定位一个文件有两种方式:
- 通过路径
- 直接找到目标文件的inode
两者都是最终还是要通过inode
- 简单的来说硬链接就是一个文件名和inode的映射关系,建立硬链接,就是在指定目录下,添加一个新的文件名和inode的映射关系!
那么以上两者都有什么作用呢?
-
其实在我们linux机器上有很多的软硬链接
-
就比如
/
目录下就有很多软硬链接
- 硬链接的场景也有很多,比如平时我们创建一个文件夹默认的计数就是2,因为里文件夹里面默认有
.
和..
- 当再次向这个目录里面新建目录>
- 计数+1
- 任何一个目录,刚开始建立的时候,引用计数一定是2
- 在目录A内部新建立一个目录,会让A目录i引用计数自动+1
- 一个目录内部有几个目录:A的引用计数-2
- 在Linux系统中,不允许给目录建立硬链接
查看文件信息stat命令
在Linux当中,我们可以使用命令stat
文件名来查看对应文件的信息。
这其中包含了文件的三个时间信息:
Access: 文件最后被访问的时间。
Modify: 文件内容最后的修改时间。
Change: 文件属性最后的修改时间。
- 当我们修改文件内容时,文件的大小一般也会随之改变,所以一般情况下Modify的改变会带动Change一起改变,但修改文件属性一般不会影响到文件内容,所以一般情况下Change的改变不会带动Modify的改变。
- 我们若是想将文件的这三个时间都更新到最新状态,可以使用命令
touch
文件名来进行时间更新。
注意: 当某一文件存在时使用touch命令,此时touch命令的作用变为更新文件信息。
取消软硬链接unlink
- 直接使用该命令即可
unlink 文件名