【从浅学到熟知Linux】基础IO第三弹=>文件系统介绍、软链接与硬链接(含磁盘结构、文件系统存储原理、软硬链接的创建、原理及应用详解)

本文主要是介绍【从浅学到熟知Linux】基础IO第三弹=>文件系统介绍、软链接与硬链接(含磁盘结构、文件系统存储原理、软硬链接的创建、原理及应用详解),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

🏠关于专栏:Linux的浅学到熟知专栏用于记录Linux系统编程、网络编程等内容。
🎯每天努力一点点,技术变化看得见

文章目录

  • 理解文件系统
    • 物理角度认识磁盘
    • 逻辑角度认识磁盘
      • 磁盘寻址
      • 磁盘中的寄存器
    • 磁盘存储管理
  • 软链接与硬链接
    • 软链接
    • 硬链接


理解文件系统

在计算机中存在着已经被打开的文件,也存在着没有打开的文件。由于内存空间较小,资源较为紧张,故没有打开的文件都会存储在磁盘上。此时,我们会关注哪些问题呢?无非是文件如何存储在磁盘上的,如何获取该文件的属性和文件内容,磁盘上读取文件效率,不同路径上的文件如何被分门别类地存储在磁盘上的。下面,我们就一起聊聊文件系统中如何管理各个文件的。

物理角度认识磁盘

磁盘是计算机上唯一的机械设备,但现在计算机多采用固态硬盘(SSD)替代了磁盘,这里仅讨论磁盘。磁盘是外设中的一种,它是通过磁盘的磁性(N/S级)存储0或1,属于永久性存储介质。(ps:非永久性存储设备,如内存,其为掉电易失设备)

每个磁盘由多个盘片组成,每个盘面的上下两面均是光滑的,均可以存储数据。磁盘需要借助磁头来读取数据,故每个面需要一个磁头,即一个盘片上的上下两个盘面均有一个磁头(一个盘面合计2个磁头)。而磁盘读取盘面上某个位置的数据时,通过摆动磁头和转动盘面来实现。
在这里插入图片描述

磁盘中的每个盘面,以中心向外,划分了不同的同心圆,这些同心圆称为磁道,如下图左侧所示。两个磁道与两半径构成的扇形区域称之为扇区,如下图右侧所示。磁盘被访问的基本单元就是扇区,扇区的大小一般为512字节或4KB。我们可以把磁盘看作无数个扇区构成的存储介质。
在这里插入图片描述
在磁盘中,定位某个扇区的方法是:①磁头左右摆动定磁道(也称为柱面);②确定数据在哪个盘面,确定具体从哪个磁头读取数据;③盘面转动确定扇区。这种方法简称为CHS(Cylinder、Header、Sector)。

【示例】若要读取下图左侧中,橙色方块处的数据(假设已经确定使用哪个磁头读取的情况下)。
①磁头摆动到指定磁道上,即确定读取的磁道。
在这里插入图片描述

②一个磁道上,包含许多个扇区,需要通过转动盘面来确定扇区。转动后,如右图所示,此时可以读取数据存储区域的内容了。
在这里插入图片描述

由于磁盘属于机械设备,它的整体速度较慢。故在使用磁盘时,要让磁盘运动越少,效率才能越高;若磁盘运动越多,则效率越低。同时,我们也意识到:具有相关性的数据要存储在一起,这样可以减少磁盘运动。

逻辑角度认识磁盘

磁盘寻址

在十年前左右,流行使用磁带听读英语。磁带中的塑料带被卷成圆圈,但实际读取是线性读取的。如下图右侧所示,当我们将磁带中的塑料袋拉出来,可以看出,它存储数据是线性存储的。
在这里插入图片描述

我们也可以将磁盘看作线性结构。即将磁道上的扇区按照某种规则,给予线性顺序编号。如下图所示,从左向右依次是盘面1、盘面2、盘面3…;每个盘面内,从左向右分别是该盘面的不同磁道;每个磁道又由多个扇区组成。(这里我们假设每个磁道的扇区个数相同)
在这里插入图片描述

【示例】假设有一个磁盘,它的每个盘面有50个磁道,每个磁道有400个扇区(即一个盘面有20000个扇区)。若某个文件存储在第28888号扇区中,则它属于哪个盘面的哪个磁道的哪个扇区呢?

盘面号 = 28888 / 20000 = 1号盘面(即第2个盘面),磁道号 = 8888 / 400 = 22 号(即第23个磁道),扇区号 = 8888 % 400 - 1 = 87号扇区(即第88个扇区)。

像上述示例中寻找扇区的方式,称为LBA寻址方式(又称为逻辑寻址方式)。

磁盘中的寄存器

不仅CPU中包含寄存器,其他外部设备中也存在寄存器。如果某个进程要向磁盘中写入数据,则需要将磁盘中的r/w寄存器标志为写状态,将要写入的数据放入数据寄存器中,将要写入的地址空间首地址写入地址寄存器。当磁盘完成当前读写操作后,磁盘会将状态寄存器改为读写失败或读写成功(在读写时,则标志为正在读写)。

ps:这里仅仅要说明,磁盘中也包含寄存器,并未列出磁盘中的所有寄存器。

在这里插入图片描述

磁盘存储管理

由于一个磁盘中包含大量的扇区,为了方便管理,我们可以将一个磁盘划分为多个扇区。但每个分区依然包含许多扇区,我们可以进一步将每个分区划分为多个块组(Block Group),每个块组中包含该块组的数据存储情况及具体的数据。

假设,有一个800GB的磁盘,先将其分为5个区,第1个200GB,第2个100GB,第3个150GB,第4个150GB,第5个200GB。

在这里插入图片描述

由于每个分区的存储空间依然很大,每个分区被进一步分为不同的块组(Block Group)。

★ps:在某些分区中会在分区开头存储一个Boot Block(引导块),Boot Block用于存储引导加载程序,这个程序负责在系统引导时加载操作系统,并启动计算机。Boot Block用于启动系统,是关键的数据,它在其他分区中也可能被重复存储,以保证某个分区存储的Boot Block出问题时,能从其他分区读取并启动系统。

而每个块组(Block Group)开始处包含着该块组的描述信息,描述信息后面才是存储的具体数据。每个块组第一个存储的Super Block(超级块),而接下来的Group Descriper Table包含了当前块组的信息,包含剩余的块数、inode数量等。接下来,我们再来聊聊余下的4个区域:Block BitMap、Inode BitMap、InodeTable及Data Block。

★ps:Super Block是文件系统中的一个关键数据结构,用于存储文件系统的整体信息,包括文件系统的大小、单个数据块大小等;Super Block提供了文件系统的基本参数和元数据,使操作系统能够正确地管理文件和目录(为了保证文件系统能安全运行,避免因当前Super Block存储区域错误导致文件系统无法访问,故Super Block也被存储了多份)。

文件的数据包含文件属性及文件内容。Linux 系统在磁盘存储文件时,将文件的属性和数据分开存储。其中,文件的内容存储在数据块中(Data Block,以块的形式程先,常见的块大小为4KB),而文件的属性存储在Inode中(Linux系统中规定,单个文件的所有属性占128字节)。

一个文件有特定的一组属性,而属性存放于Inode中,即一个文件配有一个Inode。为了保证Inode的唯一性,每个Inode的编号是唯一的。我们可以通过ls -li查看当前目录下所有文件的Inode↓↓↓
在这里插入图片描述
也可以通过stat [文件名]查看某个文件的Inode↓↓↓
在这里插入图片描述
Inode中保存着对应文件的文件类型、权限、引用计数、所属组、所有者、ACM时间、文件存储在哪些数据块中等。
★注意:Linux系统中,文件的属性不包含文件名

★ps:Linux系统中,一个文件一个Inode,每一个Inode都有自己的Inode编号。Inode的设置,是以分区为单位的,不能跨分区。

Inode存储文件的所有属性,文件名不属于Inode内的属性!那我们怎么知道一个文件的Inode的编号?使用者从来没有关心过Inode,用的都是文件名。

关于上面这个问题,我们就需要聊聊Linux中的目录了!那怎么理解目录呢?目录本质也是文件,也有自己的inode,因为目录也有自己的属性↓↓↓
在这里插入图片描述
而目录也有自己的存储内容,目录的内容中存储着该目录中包含了哪些文件。既然有数据,故目录也要有自己的数据块。那里面存的具体的内容就是它所包含的各个文件名与其Inode的映射关系。因而,使用者只需要使用文件名就可以访问一个文件了(因为有了文件名,就能在当前目录的数据块中找到该文件名映射的Inode,也就能访问该文件了)。

有了上面的认识,我们可以总结出以下内容:

  • ①为什么同一个目录下不能存在同名文件呢?
    因为文件名与Inode的映射关系唯一,如果存在同名文件,则会存在多个文件映射到用一个Inode的情况,故一个目录下不能存在同名文件。
  • ②如果没有一个目录的w权限,则不能在该目录下创建文件,这是为什么?
    在文件中创建文件,需要将文件名与Inode的映射关系写入该目录的数据块中,由于没有w权限,故无法写入数据块。
  • ③如果没有一个目录的r权限,则不能查看目录中的文件存储情况,这是为什么?
    要查看目录中存储的文件情况,则需要读取目录的数据块,由于没有r权限,则不能读取。
  • ④如果没有一个目录的x权限,则不能进入该目录,这是为什么?
    可以将目录假想成一个程序,要进入这个目录就要执行这个目录,由于没有x权限,故无法进入。

BlockBitMap:比特位的位置与块映射起来,比特位的内容表示该块是否被使用。
InodeBitMap:比特位的位置和Inode编号映射起来,比特位的内容表示该Inode是否有效(是否被使用)。

  • 新建一个文件,系统做了什么?

①在InodeBitMap申请一个Inode;
②在BlockBitMap申请当前文件需要的对应数量的Data Block,并在这些Data Block中存储文件的内容;
③并在InodeTable中找到申请的Inode,存储该文件的信息及申请了哪些Data Block;
④在当前目录的Data Block保存该文件的文件名与Inode的映射关系。

  • 删除一个文件,系统做了什么?

①将文件存储内容的块在BlockBitMap中的对应位置设置为无效;
②将文件存储属性的Inode在InodeBitMap中的对应位置设置为无效;
③删除当前目录的数据块中存储的该文件与Inode的映射关系。
ps:不需要情况Inode和Data Block中的数据,等下一个文件直接覆盖该文件的内容即可。

  • 修改or查询一个文件,系统做了什么?

①在当前目录的数据块中,通过文件名找到该文件的Inode;
②从Inode中获取文件的属性信息及文件内容存储在哪些Data Block中;
③返回文件属性及文件内容。

★ps:为什么拷贝数据慢,而删除数据快呢?
拷贝数据数据时,需要将数据挨个比特位写入到文件对应的Data Block中;而删除数据的时候,不需要情况Data Block中的数据,只需要将该文件的Data Block对应在BlockBitMap中的位置置为无效即可。

★ps:为什么系统提示还有空间,但却无法创建文件呢?
Inode还有但DataBlock没有了,或Inode没了但DataBlock还有。

软链接与硬链接

软链接

建立软链接的方法

ln -s [file-name] [soft-link-name]

在这里插入图片描述
我们可以通过软链接向file1中写入"Jammingpro"↓↓↓
在这里插入图片描述
我们再来看一下file1与soft-file1的inode↓↓↓
在这里插入图片描述
由上面的结果可知,软链接是一个独立的文件,因为它有独立的inode,故它们的数据块(Data Block也是不同的)。软链接中存储的是file1的路径

当访问软链接时,它会到对应的路径中找到file1的文件名与inode的映射关系,并访问对应的inode。软链接就类似与Windows中的快捷方式(它在Linux系统中的应用也是用于创建快捷方式)↓↓↓
在这里插入图片描述
如果要删除软链接,除了使用rm [软链接名称],也可以使用unlink [软链接名称]↓↓↓
在这里插入图片描述

硬链接

创建硬链接的方法

ln [file-name] [hard-link-name]

在这里插入图片描述

从上面的建立结果可以看出,file1在创建硬链接前的引用计数为1,当建立硬链接后的引用计数变为了2。我们再来看看者两个文件的信息↓↓↓
在这里插入图片描述

两个文件除了文件名不同,其他信息(Inode编号,占用数据块数量、大小等)均相同。故所谓建立硬链接,本质其实就是在特定的目录的数据块中新增文件名和指定文件的Inode编号的映射关系,并将对应文件的引用计数+1。也就是说,硬链接就是给对应的文件取别名。

★ps:任意一个文件(无论是目录还是普通文件)都有Inode,每个Inode内部都有一个叫做引用计数的字段。只有该文件的引用计数变为0时,该文件的Inode及Data Block才会被删除。

硬链接用途有什么呢?关于它的用途,我们需要先来探索关于目录的一些问题↓↓↓

为什么我们创建文件夹的使用,它的引用计数为2呢?
在这里插入图片描述
下图查看了dir的Inode,并进入dir中,查看了.的Inode。可以看出,dir的Inode与.的Inode是相同。也就是说,当我们创建目录时,会在该目录中自动创建一个该目录的硬链接,其名称为.。
在这里插入图片描述
如果在dir目录中创建一个名为start的目录,可以发现,.的引用计数变为3。这是为什么呢?
在这里插入图片描述
进入start目录,可以发现该文件夹中的…的Inode与上一级目录中的.的Inode编号相同,也就说:每当在当前目录下创建一个目录,该目录中会自动创建一个名为…的上一级目录的硬链接。
在这里插入图片描述
通过上面我们可以知道,硬链接可以用于目录的跳转。因为我们使用.、…来跳转目录。但Linux并不允许用户给目录创建硬链接,这是为什么呢?

假如我们将某个目录中的.和…均改为根目录,则此时会出现环结构。当我们使用搜索指定时,就会出现无穷循环的现象。

🎈欢迎进入从浅学到熟知Linux专栏,查看更多文章。
如果上述内容有任何问题,欢迎在下方留言区指正b( ̄▽ ̄)d

这篇关于【从浅学到熟知Linux】基础IO第三弹=>文件系统介绍、软链接与硬链接(含磁盘结构、文件系统存储原理、软硬链接的创建、原理及应用详解)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/922979

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Linux使用nload监控网络流量的方法

《Linux使用nload监控网络流量的方法》Linux中的nload命令是一个用于实时监控网络流量的工具,它提供了传入和传出流量的可视化表示,帮助用户一目了然地了解网络活动,本文给大家介绍了Linu... 目录简介安装示例用法基础用法指定网络接口限制显示特定流量类型指定刷新率设置流量速率的显示单位监控多个

Debezium 与 Apache Kafka 的集成方式步骤详解

《Debezium与ApacheKafka的集成方式步骤详解》本文详细介绍了如何将Debezium与ApacheKafka集成,包括集成概述、步骤、注意事项等,通过KafkaConnect,D... 目录一、集成概述二、集成步骤1. 准备 Kafka 环境2. 配置 Kafka Connect3. 安装 D

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法

《ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法》本文介绍了Elasticsearch的基本概念,包括文档和字段、索引和映射,还详细描述了如何通过Docker... 目录1、ElasticSearch概念2、ElasticSearch、Kibana和IK分词器部署

Linux流媒体服务器部署流程

《Linux流媒体服务器部署流程》文章详细介绍了流媒体服务器的部署步骤,包括更新系统、安装依赖组件、编译安装Nginx和RTMP模块、配置Nginx和FFmpeg,以及测试流媒体服务器的搭建... 目录流媒体服务器部署部署安装1.更新系统2.安装依赖组件3.解压4.编译安装(添加RTMP和openssl模块

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

Spring Cloud LoadBalancer 负载均衡详解

《SpringCloudLoadBalancer负载均衡详解》本文介绍了如何在SpringCloud中使用SpringCloudLoadBalancer实现客户端负载均衡,并详细讲解了轮询策略和... 目录1. 在 idea 上运行多个服务2. 问题引入3. 负载均衡4. Spring Cloud Load

linux下多个硬盘划分到同一挂载点问题

《linux下多个硬盘划分到同一挂载点问题》在Linux系统中,将多个硬盘划分到同一挂载点需要通过逻辑卷管理(LVM)来实现,首先,需要将物理存储设备(如硬盘分区)创建为物理卷,然后,将这些物理卷组成... 目录linux下多个硬盘划分到同一挂载点需要明确的几个概念硬盘插上默认的是非lvm总结Linux下多

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录