朋友们、伙计们,我们又见面了,本期来给大家带来文件系统相关知识点,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成!
C 语 言 专 栏:C语言:从入门到精通
数据结构专栏:数据结构
个 人 主 页 :stackY、
C + + 专 栏 :C++
Linux 专 栏 :Linux
目录
1. 文件管理
我们计算机里面的文件有很多,前面的文件fd章节主要理解被打开文件如何进行管理,那么众多的文件不一定全都要被打开,当前不需要访问的文件处于未被打开的状态,这些文件都在磁盘中保存,对于这些没有被打开的文件也需要进行管理,管理未被打开的文件的核心工作就是当我们需要访问的时候可以快速的定位到该文件。
文件的管理工作:
1. 对打开的文件在内存中管理;
2. 没有被打开的文件在磁盘中管理。
文件系统主要是管理文件的存储问题,文件 = 内容 + 属性,本质上是管理文件的内容和属性的存储问题,将文件管理起来的最主要的目的就是为了方便OS/用户对于文件的各种访问操作(增删查改)。
2. 磁盘物理存储结构
磁头的运动轨迹是左右,磁盘的运动轨迹是旋转;
磁盘访问任意位置的时候都是机械运动,这就表明了磁盘的访问速度是较慢的。
2.1 基本概念
通过图片可以看到磁盘的盘面上分成的若干个扇区,这些扇区用来存储数据,需要注意的是,这些小扇区存储数据的大小都是一样的,通常是512字节(4KB)。
- 一个盘面可以有很多个同心磁道;
- 一圈磁道可以有很多扇形的扇区;
- 扇区是磁盘最小的存储单元,大小为512字节(4KB)。
磁头摆动定位柱面、盘片旋转定位扇区。
2.2 向磁盘写入数据
根据磁盘的物理存储结构,向磁盘写入数据时的寻址定位方法:
- 1. 选择哪一面(盘面),本质上就是选择磁头;
- 2. 选择该盘面上的哪一个磁道;
- 3. 选择该磁道上的哪一个扇区。
这种寻址定位方法叫做CHS定位法。
我们可以向一个扇区写入,就可以向多个/任意一个扇区写入,当然也可以随机写入;
3. 磁盘逻辑抽象结构
观察磁盘的物理结构不难发现其实和我们C语言中学到的二维数组很相似,二维数组也是连续存储结构,所以我们可以将磁盘的结构抽象成一个数组,将磁盘的盘片想象成线性空间,所以我们对于磁盘的管理,就可以变成对于数组的管理!同样的可以使用数组的下标来快速定位到内容的具体位置。
操作系统可以按照扇区为单位进行数据的存取;
还可以基于文件系统,按照文件块为单位进行数据的存取。
所以在OS层面,对于存储设备的管理,转化成了对于数组的增删查改!
4. 文件系统
操作系统可以基于文件系统,按照文件块为单位进行数据的存取,一个文件块的大小只有4KB,但是一个磁盘的大小可能是500GB或者1TB,那么该怎么对这么大的空间做管理呢?
可以采用一种分治的方法,分成若干个相同的区域,对一个区域的管理工作可以嵌套到其他区域;
分区和分组
假设有一块500GB的磁盘,首先进行分区,划分成5个100GB空间的区域,然后再对100GB的区域进行分组,将100GB的区域再分成50个2GB的小组,此时,对于500GB磁盘的管理工作就变成了对于2GB的小组的管理工作。
文件 = 内容 + 属性,内容和属性都是数据,所以内容和数据分开存储;
在分成的这些小组中,不仅要存储文件自身的数据,还要存储管理文件者的数据,每次分组,都要先把管理者的信息数据存储进去,这个过程就叫做格式化。
那么就来看看这一个小组如何管理:
Boot Block:表示的就是起始的位置,比如第0个盘面,第0个磁道、第0个扇区。
在这每一个小组中都有管理这个小组的一些字段,我们一个一个来看一下:
Data blocks:该字段叫做数据区,存储文件内容,以4KB的块为单位;
如果要保存的一个文件的内容太大,数据区中的这些分块不单单只是直接映射的关系,还会有间接映射(一个块中保存下一个块位置),三级映射(一个块中保存多个块的位置)。
如果文件内容把数据区全部占满了还是没有存下,此时就会考虑到跨组的问题,会在一个块中保存下一个组的位置信息。
inode Table:该字段叫做节点表,用于存放文件属性,如大小、权限、inode编号、拥有着、所属组、修改时间等;
它是一个表,所以就不止一个文件的属性,在这个表里面管理着很多文件的属性;
所以文件属性是通过inode保存的,就表明了它也是一个结构体对象,里面有描述文件属性的字段;
struct inode { int ref_count; // 指向该inode的引用计数 // 文件大小 // 文件权限 // 文件inode编号 // 文件拥有者 // 文件所属组 // ...... int blocks[N]; // 保存文件内容在数据区的哪个位置 // ...... }
一个文件的inode编号是什么呢?在命令行中输入ll -li
- 一般情况,一个文件对应一个inode,基本上,每个文件都要有它自己的inode;
- inode在整个分区上具有唯一性;
- Linux内核中,识别文件和文件名无关,只和inode有关。
所以我们可以通过一个文件的inode知道该文件的内容数据存储在数据区的哪几个位置;
- inode Bitmap(inode位图):它是一个位图,每一个bit位表示一个inode是否空闲可用,比特位为0/1表示对应的inode是否被使用;
- Block Bitmap(块位图):它也是一个位图,比特为为0/1表示Data Block中对应的数据块是否被占用;
- GDT(Group Descriptor Table):块组描述符,描述块组属性信息;
- 超级块(Super Block):存放文件系统本身的结构信息。记录的信息主要有:bolck 和 inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了(不一定每个组都有)。
inode的唯一性只在整个分区,那么在访问文件最开始的时候,怎么知道文件在哪个分区?
每一个文件都有路径,可以通过路径的前缀判断,我们的文件处于哪一分区!
4.1 新建文件和删除文件
新建文件:
如果我们要新建一个文件,首先在块位图中找到数据区中未被使用的区域,然后将文件内容数据填入数据区,并且将块位图对应的位置修改,然后在inode位图中找哪个inode未被使用,然后将inode分配给该文件并填充inode表信息,并将inode位图对应的位置修改。
删除文件:
删除文件时只需要将块位图和inode位图对应的位置进行修改即可。
4.2 理解目录
目录也是文件,所以也有自己对应的inode,那么目录的内容存储的是什么呢?
在目录的数据块中存储的是该目录下的所有文件名和inode的映射关系;
所以在同一个目录下不能出现同名文件。
回归之前的文件权限:我们要想在一个目录下对一个文件进行新建、删除、修改,此时就需要具备写入权限("w"),因为目录的内容是该目录下的文件名和inode映射关系。
Linux中,文件名不属于文件属性!
4.3 查找文件
要查找到一个文件,内核只认识inode编号,所以就要找到该文件的目录,因为目录里面保存的是改目录下的文件名和inode的映射关系,那么又该怎么找到这个目录呢(目录也是文件)?
一个磁盘在被分区格式化之后,Linux要是用这个分区,就先要把这个分区进行挂载mount
所以就可以根据一个文件的路径然后逐一进行剥离就可以找到该文件。
5. 软硬链接
- 软链接:软链接是一个独立的文件,有自己的inode,软链接的内容是指向的目标文件的路径,类似于windows的快捷方式;
- 硬链接:硬链接不是一个独立的文件,是在指定目录内部的一组文件名和inode的映射关系!
软链接可以创建一个指向特定文件或目录的快捷方式,方便用户快速访问。
硬链接允许多个用户或进程同时访问和修改同一文件,而不需要进行复杂的文件共享设置。
建立软硬链接的方法:
建立软链接:ln -s 文件名 软链接名
建立硬链接:ln 文件名 硬链接名
当我们创建一个普通文件时,它的硬链接数目是1,但是创建一个目录时,它的硬链接是2,这是为什么呢?
当我们创建一个目录时,目录中默认会有两个隐藏文件,一个是. 另一个是..
如果我们仔细观察它的inode就可以发现,.文件的inode和test目录的inode一样,所以新创建目录的硬链接数目是2;
..文件表示上级目录,所以我们可以根据它的inode来验证一下:
一个文件在什么时候算是真的被删除了呢?
没有文件名和inode映射时,在系统层面,inode内部有引用计数,表明有几个文件名映射关系,所以当引用计数为0时就表示这个文件没有人用了。
文件名在目录里面具有唯一性,所以文件名类似于指针。
Linux中不允许对目录新建硬链接:
朋友们、伙计们,美好的时光总是短暂的,我们本期的的分享就到此结束,欲知后事如何,请听下回分解~,最后看完别忘了留下你们弥足珍贵的三连喔,感谢大家的支持!