摘要:主要介绍了Linux文件存储的原理,以及硬链接和软链接的区别
有点标题党了,其实主要是想讲讲Linux文件存储的原理,也就是inode,以及硬链接和软链接的区别。
话说有一个场景,数据文件存储在一个个分级的目录下,简单的描述一下,类似以下的结构:
- 目录1
- 文件1.1
- 文件1.2
- 文件1.3
- 目录2
- 文件2.1
- 文件2.2
- 目录3
- 文件3.1
- 文件3.2
- 目录n
- 文件n.1
- 文件n.2
我们现在想把文件1.2、文件2.1、文件3.1、文件……、文件n.1发送给其他人。最简单的方法是,将我们需要的文件都复制到同一个目录下,打包,下载到本地,或者直接复制到其他服务器上。
现在的问题是,这些数据文件很大,每个文件动辄好几g,如果每个文件都复制一份,会耗时耗空间。
大佬过来看一眼,说:你创建这些文件的硬链接到你的指定目录,不就行了?不占空间。
我说:啥?啥是硬链接?
1、文件是怎么存储的?谈谈inode和数据块
讲硬链接之前,我们需要先了解一下前置知识:Linux是怎么存储文件的。
文件自然是保存在磁盘上的,但是是以什么样的形式、什么样的结构存储的呢?
操作系统一般会将磁盘分为一个个的块(block)来读取,而这个块,就是存储文件的最小单位。一般一个块占据4k的磁盘空间。文件的数据,就会存储在磁盘的一个个块中。
而一个文件除了数据部分,还有文件自身的一些属性信息,比如:文件的大小、权限、修改创建时间、指向数据块的指针等等。这些信息叫作文件的元数据,不存储在块里,是存储在叫inode的区域中。每个inode的节点大小一般是128或256字节,且都会有一个inode号码,来唯一标识一个inode。
因此,磁盘在格式化时,会将磁盘分为两个部分:数据区和inode区。每1k或者2k的数据区,需要留存一个inode。这样的设计,正常情况下inode的数量是足够的,但是极端情况下,即便磁盘还有空间,但是inode区已经用光了,所以会导致无法创建文件。
2、读取文件过程
由以上可知,一个文件包含两部分数据:
- 元数据,保存在inode中。一个文件只会占用一个inode。
- 文件数据,保存在数据块(data block)中。一个文件因为数据量大小不同,会占用多个数据块。
inode中会保存指向数据块的指针,根据指针可以找到该文件存储的数据块。
另外,想要读取文件,这里还需要知道一个目录项(directory entry)的概念。
一个目录项会保存当前文件的文件名称和inode号码。而这个文件名称,就是你在Linux系统中看到的文件名称。
所以,你看到的文件,只是这个文件名。而对于Linux而言,它看到的文件是唯一的inode。你在读取一个文件时,Linux会通过文件名和inode号码的映射,找到inode,再根据inode保存的指针,找到文件数据存储的数据块。目录项、inode、数据块之间的关系如下:
3、复制、硬链接和软链接
回到硬链接的话题。
比如现在有一个文件fileX,文本内容为“hehe”,我们用ll -i命令来查看一下:
使用-i这个命令,我们可以看到文件对应的inode号码。
此时我们复制这个文件,得到结果如图:
我们可以看到,复制出来的文件fileXBackup,他的inode号码和源文件fileX的inode号码不一样,说明我们复制了一个Linux认为的全新的文件。
再用命令ln来对文件fileX创建一个硬链接,结果如图:
看,创建的硬链接hard,其对应的inode号码,和源文件fileX是一致的。所以对于我们来说,是创建了一个新的文件,但是对于Linux来说,还是那个inode,不多不少。
现在我们再创建一个软链接,如图:
可以看到,软链接文件soft的inode号码,是一个新的号码,且有颜色标识和箭头指向源文件fileX。所以这个soft是一个指向fileX的文件。
现在我们尝试修改修改fileX文件,在其尾部追加文本。
echo "xixi" >> fileX
再分别查看fileXBackup、hard和soft这三个文件,如图:
因为hard和fileX对于linux来说,都是同一个文件,自然是一样的。而soft因为指向的是fileX,因此内容也是一致的。
现在我们删除fileX,再看一下hard和soft是否还能打开。
我们可以看到,soft指向的fileX已经被标红,且无法打开。hard依旧可以正常打开。因为删掉的只是我们眼中的fileX,而Linux眼中inode值为1838442的文件还在。
4、直接通过inode获取文件
理解了上述概念,是不是会萌生一个想法。既然Linux只认inode,那我们能不能直接通过inode找到文件呢?
实际上,如果我们知道一个文件的inode号码,则可以通过find命令,找到对应的文件,并做相应的处理。比如我们要查看上面提到的hard文件,则可以用以下命令:
find -inum 1838442
便可以查找到对应的文件。当然,我们也可以用find命令的-exec参数来直接操作该文件:
find -inum 1838442 -exec cat {} \;
结果如下:
一般在无法处理文件名有乱码的情况下,可以使用这个方式来处理文件。
5、总结
Linux存储文件时,会将文件分为两部分。文件的数据存储到磁盘的一个或多个数据块中,文件的元数据(自身属性)存储在inode区中的一个节点上。
我们看到的文件和目录,是目录项中展示的表象。本质上想查看一个文件,需要通过目录项找到inode,再根据inode找到指向的文件数据块。站在Linux角度,一个inode才是一个文件。目录项中多个文件指向同一个inode,那也是按照同一个文件去处理。
复制、硬链接和软链接的差别:
- 复制是创建一个目录项中的文件,指向一个新的inode,在磁盘上开辟一个新的空间。
- 硬链接本质上是创建一个目录项中的文件,指向一个inode,还是原有的空间。
- 软链接则是创建一个链接,指向目录项中的文件。该文件删除后,软链接自然失效了。
参考资料
https://www.kernel.org/doc/html/latest/filesystems/ext4/inodes.html
https://www.kernel.org/doc/html/latest/filesystems/ext4/ifork.html
https://www.kernel.org/doc/html/latest/filesystems/ext4/directory.html
评论区