目录
磁盘文件管理
认识磁盘
抽象认识磁盘
磁盘划分
inode vs 文件名
软硬链接
前面我们说了关于 Linux 文件系统中 “已打开的文件” ,但是在系统中可不光只有已打开的文件,实际上,系统中还存在很多没有打开的文件。
既然有很多还没有打开的文件,那么没有打开的文件存储在哪里呢?
实际上这个问题我们也是知道的,没有打开的文件存储在磁盘之中。
我们知道:文件 = 内容 + 属性
那么我们站在单个文件的角度:
我们要不要知道单个文件的大小呢?我们要不要知道文件的属性呢?
那么我们站在系统的角度:
我们要不要知道总共有多少文件呢?我们要不要知道还能存储多少数据呢?如何可以快速的检索一个文件呢?
上面的都是关于没有打开的文件的问题!
我们平时所说的内存是 “带电的”,也就是数据是易失的。
如果内存断电的话,那么里面的数据就丢失了。
而磁盘是永久的,其实还有一些永久的存储介质,例如:SSD、U盘、光盘、磁带...
我们要知道,由于计算机只认识二进制,所以对于内存来说,内存是带电的,可以使用有无电来表示二进制。
那么对于磁盘来说,如何表示呢?而且磁盘是永久的,也就是说有什么介质可以表示二态呢?磁铁!!!
磁铁本来就可以分为南北两极,所以可以使用小的磁铁来表示。
磁盘结构:
盘面
扇区
柱面(磁道)
磁盘的数据就存储到扇区里面,而扇区的一般大小为 512 字节,但是现在也有 4kb 扇区的磁盘。
所以如果要想找数据,但是数据又存储到扇区里面,那么要如何找呢?
要想知道数据在哪个扇区,那么首先当然需要确定对应的扇区在哪个盘片,也就是知道对应的磁头。
那么知道了在哪个盘片上,我们要想找一个扇区,我们也需要知道对应的磁道。
知道对应的磁道后,就可以找到对应的扇区了。
所以这种寻址方法也叫做:CHS
C:表示柱面
H:表示磁头,磁头也对应的是盘面
S:表示扇区
虽然磁盘上又 CHS 地址,但是系统并不使用这种地址。
而是使用一种 LBA(logical block address),其中不使用 CHS 地址主要是为了让系统与外设解耦!
但是 CHS 可以转化为 LBA 地址,其中 LBA 地址类似于一整个数组。
所以我们也可以将磁盘抽象理解为一整个数组
所以我们现在可以认为,磁盘就是一整个大数组,但是如果操作系统要对这么大的数组进程管理,显然是不好管理的。
那么怎么办呢?其实操作系统可以将这么大的数组划分为一段一段的小数组来进行管理,只要管理好其中的一小块数组,那么就可以管理好这么大的一整个数组,也可以称为 “分治”。
所以就把 磁盘的管理 -> 小分区的管理
那么如何对这么大的数组进行划分呢?
既然可以理解为数组,那么其实也就是对数组的划分。
那么我们可以将前一部分划为为一组,在将后一部分划分为一组。
也就像上面一样,将一个 500G 的空间划分为三份。
那么就是对这些小的分区的管理。
然后下面可以接着划分,我们将每一个分区又进行划分,首先刚开始的位置放的是 Boot Block.
Boot Block : 引导块。
作用:用于加载操作系统的内核
后面的就是每一个 :块组0 ... 块组n。
这里的 super block:记录了文件系统中整体的信息,包括大小、块大小、inode数量、已使用的块和inode数量等信息。
其实我们并不关注这个,我们要知道文件的内容和属性存储,以及如何快速知道哪一个块没有存储。
所以后面的内容才是我们关注的。
下面我们挨个介绍一下这些内容:
在 Linux 中,系统与磁盘的交互并不是以一个扇区内容为主,而是以 4kb 为主,这样做有两个原因:
一般的扇区为 512 字节太小了,所以可能会进行多次 IO 导致系统效率降低。
如果系统采用了磁盘的扇区大小为交互,那么就和磁盘强相关了,如果磁盘扇区变化,那么系统代码也需要改变了,所以为了实现解耦。
在 Linux 文件系统中,文件的内容和属性其实是分开存储的,而文件的内容就存储在 data block 中。
文件的属性存储在 inode table 中。
而其中一个文件对应一个 inode table,只要找到 inode table 就可以拿到对应文件的属性。
Data Block:就是文件内容存储的位置,而 Date Block 就是多个 4kb 的集合。
inode Tbale:inode 大小为 128 字节,inode里面存的是对应文件的属性,所有文件的inode文件的集合,都要有一个inode编号,一般而言,一个文件,一个inode,一个inode编号。
Block Bitmap:是一个位图,表示的是哪一个 data block 被使用或者是没有使用,如果为 1 表示被使用,如果为 0 表示没有被使用。
inode Bitmap:也是一个位图,表示的是 inode 是否被使用,如果没有被使用,那么就是 0,否则就是 1。
Group Descriptor Table(GDT):是块组描述符,里面记录了该块组的大小,以及被使用了多少,还有就是里面的 inode 数量,被使用了多少,还剩多少,还有 block 个数,被使用了多少,还剩多少。
既然我们说了,一个文件对应一个 inode,而且再 Linux 中,文件的属性,和文件的内容是不在一款存储的。
一个文件的内容是有多有少,而文件的内容存储再 data balck 中,那么如果一个 data block 中存储不下怎么办呢?
struct inode
{
// 文件大小
// 文件 inode 编号
int block[15];// 可以存储 block 的使用情况
...
}
实际上,可以在 inode 里面存储 data block 的使用情况。
但是这里肯定是有问题的,那就是,如果一个文件的内容是几个G,甚至是几十个G呢?
那么 inode 里面一定是存储不下的!
实际上,data block 中不光可以存储数据,还可以存储下一个 data block 的位置!
所以通过 data block 中存储下一个 data block ,那么就可以解决这个问题。
通过上面的学习,我们也就知道了 inode 是和文件一一对应的。
实际上, Linux 中实际上是没有文件名的,只有 inode。
那么我们查找一个文件,我们首先要找到对应的分区。
然后到分区里面找到对应的块组,到块组里面的 inode block 找到对应的 inode。
然后找到里面文件的属性,再找到 inode 里面对应的数据。
下面再回答几个问题!
一个目录下,是不是又很多文件,但是这些文件是没有重复名字的!
目录是文件吗?是的!那么目录也一定有自己的 inode,有自己的 data block 。
但是实际上 inode 里面并不存储文件名,inode里面只存储数据。
而文件名存储在 inode 使用的 data block 中,block 中有 inode 与 文件名的映射!
而文件名也是唯一的, inode 也是唯一的,所以,其实文件名与inode是互为Key值的。
而目录中的数据就是文件,所以 data block 中保存的就是文件内容,也就是目录中的文件。
那么目录中保存的是文件,所i也就是保存的是其他文件的 inode 和文件名的映射。
所以我们再目录里面的各种操作可以如何理解:
进入目录:可以理解为到目录对应的 inode 中。
创建文件:当时我们说创建文件需要有写权限,那么就是需要我们到对应的 data block 中写入 inode 和对应文件名。
显示文件名与属性:显示文件对应的 inode。
创建文件,操作系统会帮我们做什么?
当我们创建一个文件的时候,操作系统会帮我们到特定的分区中的块组中的 inode bitmap 中找一个空的,没有使用的 inode ,然后写入文件的属性,如果有数据的话,那么还回分配对应的 data block。
删除文件,操作系统会帮我们做什么呢?
当我们删除一个文件的时候,操作系统帮我们将该文件占用的 data block bitmap 给置0,然后将该文件使用的 inode bitmap 也置为 0。
查看文件,操作系统会帮我们做什么呢?
查看一个文件的时候,操作系统会帮我们将文件对应的 inode 的属性给显示出来,如果需要显示内容的话,那么操作系统还会帮我们将文件对应的内容找到,然后将使用了的 data block 里面存储的数据给显示出来。
软硬链接
软硬链接是什么,这里我们直接看一下软硬链接。
软连接:
首先,我们先创建一个任意文件。
下面我们使用软连接,将该文件与一个文件链接起来。
ln -s 目标文件 链接文件
上面这个就是软连接的命令。
ln 表示 link,链接的意思。
-s 表示soft,要进行软连接。
下面看一下操作:
[lxy@hecs-165234 linux106]$ touch file.txt
[lxy@hecs-165234 linux106]$ ll
total 0
-rw-rw-r-- 1 lxy lxy 0 Oct 12 07:42 file.txt
[lxy@hecs-165234 linux106]$ ln -s file.txt soft
[lxy@hecs-165234 linux106]$ ll
total 0
-rw-rw-r-- 1 lxy lxy 0 Oct 12 07:42 file.txt
lrwxrwxrwx 1 lxy lxy 8 Oct 12 07:43 soft -> file.txt // 这个就是软链接后的文件
软链接后 soft 文件指向 file.txt 文件。
硬链接:
我们还是创建一个文件。
然后使用硬链接。
link 目标文件 链接文件
上面 link 就表示是硬链接
然后后面跟的是想要将链接文件,链接到木匾文件上。
下面看一下操作:
[lxy@hecs-165234 linux106]$ touch hardFile.txt
[lxy@hecs-165234 linux106]$ ll
total 0
-rw-rw-r-- 1 lxy lxy 0 Oct 12 07:42 file.txt
-rw-rw-r-- 1 lxy lxy 0 Oct 12 07:46 hardFile.txt
lrwxrwxrwx 1 lxy lxy 8 Oct 12 07:43 soft -> file.txt
[lxy@hecs-165234 linux106]$ link hardFile.txt hard
[lxy@hecs-165234 linux106]$ ll
total 0
-rw-rw-r-- 1 lxy lxy 0 Oct 12 07:42 file.txt
-rw-rw-r-- 2 lxy lxy 0 Oct 12 07:46 hard
-rw-rw-r-- 2 lxy lxy 0 Oct 12 07:46 hardFile.txt
lrwxrwxrwx 1 lxy lxy 8 Oct 12 07:43 soft -> file.txt
上面操作结束后,hard 就是 hardFile 文件的硬链接。
上面就是软硬链接。
软硬链接的区别
但是他们有什么不同呢?
当我们在查看文件的时候,我们可以 ls/ll 后面带一个选项 -i,-i 表示显示文件的 inode 标号。
我们都知道,inode 和文件是一一对应的,如果inode 不同表示不同的文件,inode相同表示相同的文件。
那么我们在仔细看一下下面的软硬链接的文件:
[lxy@hecs-165234 linux106]$ ll -i
total 0
1716544 -rw-rw-r-- 1 lxy lxy 0 Oct 12 07:42 file.txt
1716546 -rw-rw-r-- 2 lxy lxy 0 Oct 12 07:46 hard
1716546 -rw-rw-r-- 2 lxy lxy 0 Oct 12 07:46 hardFile.txt
1716545 lrwxrwxrwx 1 lxy lxy 8 Oct 12 07:43 soft -> file.txt
这里的 soft 是 file.txt 的软连接。
这里的 hard 是hardFile.txt 的硬链接。
那么我们看一下 inode 编号:
软链接的inode 编号是不同的,那么就表示软连接的文件是独立的,而软连接里面保存的就是目标文件的路径。
硬链接的 inode 和其目标文件的 inode 编号是相同的,那么说明硬链接的文件和其木匾文件使用的是同一个inode 那么也就是硬链接不是一个独立的文件。
软硬链接的作用
首先,我们可以看一下软连接的:
当我们现在有一个路径比较深的文件,那么我们总是想要在当前文件下执行,那么我们就可以在当前文件下,创建一个目标文件软连接,然后可以执行。
下面我们在当前目录下创建一个 user/bin/目录。
该目录里面有一个 Print 的可执行程序。
我们在当前目录下,使用软连接将 ./user/bin/Print 文件与 Print 文件链接起来。
这样,我们就可以在当前文件下比较方便的
[lxy@hecs-165234 linux106]$ tree user/
user/
└── bin
└── Print
[lxy@hecs-165234 linux106]$ ln -s ./user/bin/Print Print
[lxy@hecs-165234 linux106]$ ll -i
total 4
1716544 -rw-rw-r-- 1 lxy lxy 0 Oct 12 07:42 file.txt
1716546 -rw-rw-r-- 2 lxy lxy 0 Oct 12 07:46 hard
1716546 -rw-rw-r-- 2 lxy lxy 0 Oct 12 07:46 hardFile.txt
1716549 lrwxrwxrwx 1 lxy lxy 16 Oct 12 08:05 Print -> ./user/bin/Print
1716545 lrwxrwxrwx 1 lxy lxy 8 Oct 12 07:43 soft -> file.txt
1716547 drwxrwxr-x 3 lxy lxy 4096 Oct 12 07:59 user
这个应用呢,就是 windows 上的快捷方式。
下面我们在看一下硬链接的:
实际上硬链接的使用没有软链接那么多。
但是我们在创建一个硬链接看一下:
[lxy@hecs-165234 linux106]$ touch file.txt
[lxy@hecs-165234 linux106]$ ll
total 0
1716544 -rw-rw-r-- 1 lxy lxy 0 Oct 12 08:14 file.txt
[lxy@hecs-165234 linux106]$ link file.txt hard
[lxy@hecs-165234 linux106]$ ll -i
total 0
1716544 -rw-rw-r-- 2 lxy lxy 0 Oct 12 08:14 file.txt
1716544 -rw-rw-r-- 2 lxy lxy 0 Oct 12 08:14 hard
这里仔细观察一下权限后的数字。
在我们还没有链接之前呢,这个数字是1,但是当我们链接之后,这个数字就变成2了。
实际上呢,这个数字就是硬链接的数,也就是表示该文件有几个硬链接。
我们下面继续创建一个目录文件。
[lxy@hecs-165234 linux106]$ mkdir lib
[lxy@hecs-165234 linux106]$ ll
total 4
1716544 drwxrwxr-x 2 lxy lxy 4096 Oct 12 08:17 lib
这里我们看到创建的目录文件这个值默认是 2?为什么?
其实这里我们仔细一想就可以明白,目录文件里面有两个隐藏文件。
其中一个就是 . 文件, . 文件他也是文件,我们可以看一下 . 文件的 inode。
1716544 drwxrwxr-x 2 lxy lxy 4096 Oct 12 08:17 lib
[lxy@hecs-165234 linux106]$ ll -ai lib
total 8
1716544 drwxrwxr-x 2 lxy lxy 4096 Oct 12 08:17 .
1716543 drwxrwxr-x 3 lxy lxy 4096 Oct 12 08:17 ..
这里看到 . 文件的 inode 与 lib 文件的 inode 是相同的,表示 . 文件是该目录文件的硬链接。
那么下面我们到 lib 里面再创建一个目录:
[lxy@hecs-165234 linux106]$ ll -i
total 4
1716544 drwxrwxr-x 3 lxy lxy 4096 Oct 12 08:21 lib
[lxy@hecs-165234 linux106]$ ll -ai ./lib/dir/
total 8
1716545 drwxrwxr-x 2 lxy lxy 4096 Oct 12 08:21 .
1716544 drwxrwxr-x 3 lxy lxy 4096 Oct 12 08:21 ..
这里我们可以看到 lib 目录的属性,也可以看到 lib 目录里面的 dir 里面的文件属性。
而此时的 lib 目录的硬链接数变成3了,为什么?
而 dir 里面的 .. 文件的 inode 与 lib 的inode 是相同的。
所以dir目录里面的 .. 文件指向了 lib 文件。
而 dir 里面的 .. 文件也就是上级目录,正是 dir 文件。
这里也可以让我们再一次理解到 . 文件和 .. 文件。