文件系统
我们在查看系统中的文件时 使用的是文件名来辨识它们
可是操作系统辨认这些文件也用的是文件名嘛?
答案是否定的 操作系统辨识文件使用的是 inode
inode
我们都知道 磁盘文件由文件属性+文件内容两部分组成
- 文件属性: 文件的大小 创建时间等 文件属性又被称为元信息
- 文件内容: 文件中存储的数据
我们在命令行中输入 ll
即可显示当前目录下各文件的属性信息
在linux操作系统中 文件的元信息和内容是分离存储的 其中保存元信息的结构称之为inode
linux系统下一切皆文件 所以说系统中势必会存在大量的inode 为了标识这些inode 我们给它们编号 称为inode号
我们ls -i
命令即可查看文件的inode号
不论是文件属性还是文件内容都是储存在磁盘当中的
磁盘的概念
磁盘是一种永久性的储存介质 与它相对的是内存 内存是掉电易失存储介质
我们所有的普通文件都是在磁盘中存储的
在我们的冯诺依曼体系中 磁盘既可以当输入设备也可以当输出设备
磁盘的物理结构大概如下图
我们在磁盘中寻找一个文件的步骤大概如下
- 确定待寻找信息在哪个盘面
- 确定待寻找信息在哪个柱面
- 确定待寻找信息在哪个扇区
也就是说扇区是磁盘中储存信息的最小单位
磁盘的线性结构
我们要想要深入理解磁盘的结构 首先要把它想象成一个线性的状态
在一张磁盘中分为n个扇区
磁盘分区
管理一块很大的空间是很难的
就像管理国家一样 不可能一个领导班子就管理好整个国家
所以说我们会把国家划分为各个省 各个市 各个区 各个村 乃至各个街道去细分管理
划分的空间越小则越容易管理
而我们的磁盘分区则更简单 因为我们不用考虑区之间的差异性 只要将一个区分好就能将这套模板套用到各个区中
在linux操作系统中 我们可以使用该命令查看磁盘的分区
ls /dev/vda* -l • 1
磁盘格式化
当我们的磁盘分区完毕之后便会进行格式化
这种操作通常会导致现有的磁盘或分区中所有的文件被清除
简单来说 磁盘格式化就是对分区后的各个区域写入对应的管理信息
linux中EXT2文件系统的存储方案
当磁盘分区分好之后我们可以对其内部继续细分
对于每一个分区来说 分区的头部会包括一个启动块(Boot Block) 对于该分区的其余区域 EXT2文件系统会根据分区的大小将其划分为一个个的块组(Block Group)
磁盘中的启动块是一个特殊的扇区,它包含了一些机器代码,用于在计算机开机时加载操作系统到内存中并执行 通常,磁盘的第一个扇区就是启动块,无论扇区大小和分区方式如何 。启动块对于操作系统的启动非常重要,如果它损坏或丢失,可能会导致无法正常开机 。我们可以使用Bootsect.exe工具来恢复或更新您的启动块 。
所以说我们可以在每个分区中都设置一个启动块来做一个备份的作用
而对于分区中每个启动块的块组 我们还可以继续细分
每个组块都由超级块(Super Block)、块组描述符表(Group Descriptor Table)、块位图(Block Bitmap)、inode位图(inode Bitmap)、inode表(inode Table)以及数据表(Data Block)组成
其中超级块和块组描述符表不太重要
- 超级块 : 存放文件系统本身的结构信息 如inode总量等
- 块组描述符表: 描述该分区当中块组的属性信息
剩下四个就是特别重要的内容了
- 块位图 :记录着Data Block中哪个数据块已经被占用 哪个数据块没有被占用
- inode位图:记录inode Table中inode的使用情况
- inode表: 存放文件属性 即每个文件的inode
- 数据块:存放文件内容
从上面的四个概念介绍我们应该能够更深的理解 文件属性和文件内容是分开存放的
我们如何理解创建一个空文件
- 首先我们在inode bitmap中找到一个未被使用的inode
- 在inode表当中找到对应的inode 并将文件的属性信息填写进inode结构中
- 将该文件的文件名和inode指针添加到目录文件的数据块中
如何理解对文件写入信息?
- 通过文件的inode编号找到对应的inode结构
- 通过inode结构找到存储该文件内容的数据块 并将数据写入数据块
如何理解删除一个文件?
- 将该文件对应的inode在inode图中设置为无效
- 将该文件inode对应的数据块在块位图中设置为无效
有没有发现 这个步骤中我们根本没有删除任何的文件 只是设置了两个位图
所以说数据被删除之后其实短时间之内是可以被恢复的 只要将两个位图重新设置就可以
但是时间一长 我们下载了其他的文件 该区域就会被覆盖 我们的文件也就再也没办法恢复了
为什么拷贝很慢 删除很快
拷贝要经过很多步骤
- 申请inode号 填入属性数据
- 申请数据块 跟inode连接
- 拷贝被拷贝文件中的内容
但是我们删除文件的时候就只需要将inode对应的位图设置为0就可以
如何理解根目录
linux系统下一切皆文件 当然根目录也不例外
既然是文件 那么它就有属性信息和内容数据
它的属性信息被储存在inode当中 包括大小 拥有者等
它的内容我们可以把他理解为文件名和inode指针一一对应的若干组数据
软硬连接
软连接
我们在linux系统下可以通过下面的指令来简历一个软连接
ln -s makefile makefile2
我们可以使用ls -i
指令来查看它们的inode号
我们可以发现 它的inode号是不同的
接着我们可以敲出 ll
指令
我们可以发现 源文件makefile的大小远远大于它的软连接
其实我们就可以把它想象成我们windows系统中的快捷方式
如果我们将源文件删除的话 那么它的软连接也无法使用了
硬链接
我们可以通过以下命令创建一个文件的硬连接
ln makefile makefile2
我们可以输入 ll - i
命令来查看它的inode号和大小
我们发现它们的inode号竟然是一样的
也就是说其实它们指向的是同一个数据块 只要修改其中的一个数据另外一个数据也就被修改了 是不是很熟悉 这不就是我们C++中的引用嘛
我们修改了一个文件之后另外一个文件的大小也被我们改变了
此外我们ll
之后可以在权限后面看到一个文件硬链接数
软硬连接的区别
- 软连接一个独立的文件 有独立的inode和数据块 但是如果删除了源文件软连接则会失效
- 硬链接的本质是引用 当所有的硬链接被删除的时候这个文件才会被删除
文件的三个时间
在Linux系统中我们可以使用stat
指令来查看一个文件的对应信息
我们可以看到这里具有三个时间信息
简单介绍下它们
- Access: 文件最后被访问的时间
- Modify: 文件内容最后的修改时间
- Change: 文件属性最后的修改时间
这里要注意的是如果我们修改文件的内容 文件的属性一般会跟着改变(文件大小属性改变)所以说我们修改完内容之后可以看到文件的内容修改时间和属性修改时间一致 但是我们修改文件属性却不会影响内容
此外我们还需要特别注意的一点是 access是并不是实时更新的 因为我们每时每刻都在访问者不同的文件 文件的访问时间是一个高频事件 如果它实时更新的话我们的系统就会变得卡顿 而另外两项由于不常改变 所以说它们的事件是实时更新的
文件时间和makefile编译的关系
一般来说我们make一次之后系统就不会让我们继续make了
此时我们只需要改变下源文件的Mondify便可以继续编译
这也是makefile决定是否进行make的原理