Linux文件操作(innode与软硬链接)

388 阅读7分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天

零.前言

上一节中我们学习了当文件已经加载到内存中的操作,那么操作系统是如何在磁盘中寻找文件并加载到内存中的呢?本节将讲述这一内容。

一、磁盘

要了解文件在没有打开的时候的存储情况,我们就需要了解存储它的硬件:磁盘。 在计算机中磁盘属于外设范畴,它是计算机内部的一个机械设备。 在这里插入图片描述 磁盘分为机械磁盘和固态磁盘,目前的笔记本上基本都装载的是固态磁盘。 磁盘的基本单位是扇区,每一个扇区大概存储512k的数据量。 但是我们理解磁盘时要把它想象成条形结构来理解。就是将圆形磁盘看成矩形。 在这里插入图片描述 同时,我们又对这个长条形的磁盘分为不同大小的区域,就是所谓的C盘,D盘,E盘。 在这里插入图片描述

大部分计算机是只有一个磁盘的,只是将其分为不同的区域。 同时,由于每一个盘的空间较大,因此我们需要继续划分管理。 在这里插入图片描述 我们将D盘分为很多个组来进行管理,它的组头有一个BootBlock这是和启动有关的。 而每一个组我们还要进行划分管理,我们: 在这里插入图片描述 其中SuperBlock是与文件结构相关的和GroupDescriptorTable是与组相关的。不过这两个都不是本文的重点。 本文的重点在于理解BlockBitmap,inodeBitmap,inodeTable和DataBlocks。

二、文件属性与数据的存储

1.inodeTable与Datablocks

当我们存储一个文件的时候,我们不仅要存储它的属性信息还要存储它的数据信息。其中InodeTable与Datablocks分别存放的就是文件的属性信息和数据信息。 在InodeTable中有很多小块,每一个小块就是一个inode。它存放的是一个文件的属性信息。 在这里插入图片描述 在Datablocks中和inodeTable是类似的,它包含很多block单元,每一个block单元存储一定大小的信息: 在这里插入图片描述 操作系统在寻找文件时是使用inode编号来进行查找的,而不是通过文件名,文件名是用户层才进行使用的。Linux系统真正标识一个文件,是通过inode编号。每一个文件都有一个inode编号。同时在inode中还会存放文件相对应的block块中的编号。 如果是目录文件,它存放在DataBlock中的内容是目录中的文件名与inode的映射关系。

2.InodeBitmap与BlockBitmap

InodeBitmap和BlockBitmap存放的是,InodeTable和DataBlocks的位图。其中比特位的位置表示的是编号,比特位的内容表示的是是否被占用。 比如:在InodeBitmap中的数字为0000 1010,表示的就是0号位的inode没有被占用,而1号位的inode已经被占用了。 Blockmap同理。

3.举例

我们通过举一个例子来理解以上的内容:

mkdir tmp
cd tmp
touch hello.c
echo "hello bit" >hello.c
cat hello.c
rm hello.c

touch hello.c:在InodeBitmap中找到没有被占用的inode单元,把属性的信息存放进去。 echo "hello bit">hello.c:查看BlockBitp中没有使用的block单元,将其余inode建立映射,并将文件的内容存放进去。 cat hello.c:通过tmp的inode找到并查看tmp的Datablock,找到与hello.c文件名形成映射关系的inode值,通过这个inode找到对应的hello.c文件的Datablock,从而打印其中的内容。 rm hello.c:在tmp的DataBlock找到与文件名hello.c相对应的inode,只需要将inodeBitmap中的该inode位置的数字由1置为0即可。不需要对其的inodeTable与DataBlock进行操作。

这也就是为什么文件的删除非常的快,因为没有删除属性和数据,只是将是否有效删掉了。而对比于windows系统的回收站,其实在回收站中的文件并没有被删除掉,仅仅只是被换了一个目录而已。当我们不小心删除了文件,最好的做法就是什么都不做,避免内容被覆盖掉。 同理,mv指令其实只是在移动文件名与inode的映射关系。

三、软硬链接

在Linux系统下的软硬链接,我们可以理解为快捷方式。 使用ln选项来创建软硬链接:

ln -s//创建软链接 ln //创建硬链接

在这里插入图片描述 这里我们就创建了一个关于log.txt的软链接log_s。 在这里插入图片描述 创建一个硬链接log_h。 在这里插入图片描述 如果是软链接,软链接的inode和文件的inode是不同的。说明软链接新建了一个文件,它有自己的属性信息和数据块(保存的是所指文件的路径+文件名)。而硬链接的inode和原来文件的inode是相同的,说明硬链接并没有创建文件,而是增加了目录DataBlock中文件名和inode的对应关系。 前一个红色框表示的是硬链接的个数,当我们创建硬链接时,硬链接和该文件都变成了2。当该值为0的时候表示文件被删除。 当我们创建文件的时候,该值为1,但是当我们创建一个目录的时候,该值为2。 在这里插入图片描述 这是因为test目录下的.也是该目录的一个硬链接。当在该目录下再创建一个目录时,值为3,这是因为该目录下的..也表示test目录。

四、文件的时间属性

我们可以通过stat来查看文件的基本属性,比如我们新建一个file.txt。并向其中写入一定的内容。

stat file.txt

在这里插入图片描述 其中access,modify,change表示的就是文件的三个时间属性.

1.Access

Access表示的是文件的最近一次被访问时间,但是我们通过cat指令访问文件发现,文件的access时间并没有发生变化。 在这里插入图片描述 这是因为打开文件是一个高频操作,为避免大量重复刷新,在较新的Linux内核中,Access不会立即被刷新,而是有一定的时间间隔OS才会自动更新时间。

2.Modify

Modify表示的是最近一次的修改时间,时间被实时更新。

echo "hello bit">>file.txt

在这里插入图片描述

3.change

最近一次修改文件属性的时间:

chomd u+x file.txt

在这里插入图片描述 注意,当修改文件属性的时候,Modify没有发生变化。但是当修改文件内容的时候,change有可能会发生变化。这是因为修改文件内容一般都会修改文件属性,比如增加内容就会修改文件的大小属性。

4.Makefile判断文件更新的方式

mytest:test.c    
  gcc $^ -o $@    
.PHONY:clean    
clean:    
  rm mytest   

其中test.c为mytest所依赖的源文件。当Makefile进行make的时候,会检查mytest和test.c的Modify时间,正常来说肯定是test.c的Modify时间比mytest的更早(因为mytest是由test.c进行生成的)。如果我们更改了test.c中的内容,那么test.c的Modify时间就会比mytest的晚,此时Makefile会执行相应的依赖方法。 我们还可以验证一下:在没改test.c的情况下进行touch(touch一个存在的文件表示修改时间),此时就可以进行make了。 在这里插入图片描述

五、总结

我们使用整个文件的创建,使用以及删除来对文件操作进行总结。

1.touch file.txt

建立文件,首先操作系统在InodeBitmap和BlockBitmap分别找到不为1的数字,将其下标作为该文件的Inode和block的编号。并将之置为1,其中Inode只有一个,block可以有多个。

2.echo "I am the king of Asgard">>file.txt

将调用echo进程,先将标准输出关闭(close(1))在该进程中将file.txt文件使用系统调用函数open打开, 首先通过目录文件的Blocktable,找到file.txt与inode的映射。然后通过该映射找到file.txt这个文件以及它的内容,并加载到内存中,形成file结构体成为该进程的一个文件。 file.txt获得一个文件描述符,存放在该进程的files结构体中,该文件描述符就是原来标准输出的文件描述符:1。 进程通过打印函数向文件描述符为1的文件中打印内容,此时就是在向file.txt中打印内容。

3.rm file.txt

将InodeBitmap中表示file.txt文件的的数字1置为0。