Linux之理解文件系统——文件的管理

news2024/11/29 3:41:14

文章目录

  • 前言
  • 一、磁盘
    • 1.磁盘的物理结构
    • 2.磁盘的存储结构
    • 3.磁盘的逻辑结构
  • 二、文件系统与inode
    • 1.文件在磁盘中是如何存储的?
    • 2.对文件进行操作
  • 三、软硬链接
    • 1.软链接
      • 创建软链接:
      • inode
      • 删除软链接:
      • 软链接的作用:
    • 2.硬链接
      • 创建硬链接:
      • inode
      • 删除硬链接
      • 硬链接的作用
      • 目录不能自定义建立硬链接
  • 总结


前言

我们在之前的文章中讨论的都是进程和被打开的文件的关系,但是如果一个文件时没有被打开,它是否需要被管理?它该如何被管理呢?
本文介绍了文件存储的位置:磁盘,它的三种结构(物理结构、存储结构以及逻辑结构);管理文件的结构:文件系统与inode;以及文件与inode之间的关系:软硬链接等相关概念。


一、磁盘

磁盘是计算机的主要存储介质,它可以存储大量二进制数据,即使断电后也可以保证数据不会丢失。下面我们将了解磁盘的物理结构、存储结构以及逻辑结构

1.磁盘的物理结构

磁盘是外设,他也是计算机中唯一的机械结构(访问外设相对较慢的原因就是机械结构的运行速度比电流的运行速度慢)。
磁盘的盘片和盘面类似于光盘,不过磁盘是两面都是光面,光盘只有一面(盘面上存储着数据)。
像刀子一样的是磁头(每一面都有一个磁头),磁头与盘面(两者每一接触)之间有马达。一旦盘片加电,盘片旋转,磁头摆动,马达可以控制磁头摆动,控制盘片旋转。
对应的磁盘有自己的硬件电路,通过硬件电路 + 伺服系统,给磁盘发送二进制指令,让磁盘定位寻址盘面上的某个区间。

2.磁盘的存储结构

  1. 磁盘寻址的时候,其基本单位既不是bit也不是byte,而是扇区。
  2. 扇区的大小:521字节,521字节是硬件要求,对于外磁道和内磁道来说大小都是一样的,它们只是密度不同。越靠近圆心的比特位越大,外侧的比特位较小。
  3. 在单面上定位扇区:通过确定磁道,以及确定对应磁道的扇区,来具体确定该区间。确定磁道:每一个磁道都有自己的编码,磁道周长不同,但是存储大小相同。由于扇区大小是相同的,因此每一个磁道有多少个扇区也是一定的,所以每一个磁道的扇区也是有编号的,因此定位到磁道就能找到对应扇区。
  4. 机械硬盘的寻址方式:盘片不断的转动,磁头不断的摆动,就是在确认在哪个磁道。如何确定扇区?盘片的先选择就是让其磁头定位扇区。
  5. 柱面:把一系列同心的磁道压在一起,宏观上看成一个整体。一般定位的时候,(磁头、柱面、扇区)与(磁头、磁道、扇区)这两个是等价的。磁头指向的位置就是柱面的边界位置。
  6. 在磁盘中定位扇区:先定位在哪个磁道(在哪个柱面),磁道定位后,(因为,所有磁头共同进退)再去定位盘面(磁头),最后确定是哪一个扇区。

总结:在磁盘中定位一个扇区,采用硬件级别定位方法(CHS定位法):柱面(Cylinder)——磁头(Head)——扇区(Sector)

3.磁盘的逻辑结构

我们都见过磁带(复读机等机器用过),它卷起来是圆柱,将它拆开就是一条很长的线。
我们可以将磁盘盘面想想成类似的结构。站住OS的角度,它认为磁盘的盘面是线性结构,它为每一个扇区划分好了空间,整个磁道相当于一个数组。要访问某个扇区,只需要定位到对应的数组下标。在操作系统内部,我们将这种地址称为LBA(Logic Block Address),如果要将它写在磁盘上,则我们要将对应的LBA转化为对应磁盘的三维地址:CHS地址。
总结:OS中的地址为LBA,对应的磁盘地址为CHS地址。

由于OS要进行逻辑抽象,不直接使用CHS,原因:

  1. 便于管理,管理数组和管理三维立体结构两者之间,数组更好管理;
  2. 让OS的代码和硬件磁盘解耦(避免它们之间强耦合)。例如:磁盘的基本大小(每个扇区对应的存储空间)发生改变,OS的源码也要发生改变吗?我们当然不需要OS的源码发生改变。

二、文件系统与inode

1.文件在磁盘中是如何存储的?

文件在磁盘中,而磁盘的逻辑结构是线性结构。磁盘的空间很大,OS内文件系统会定制多个扇区进行读写,以1KB、2KB、4KB为单位,即使读取/修改1bit的内容,也必须将4KB的内容加载到内存中进行读取或修改,完成操作后再将其写回磁盘。虽然磁盘的访问的基本单位是521字节,但是还是相对于整个磁盘的大小还是很小的。
为了方便管理,我们采用分治的思想,对磁盘空间进行分区:1个较大的磁盘空间 ——> 多个较小的磁盘空间,再给不同的分区写入不同的文件系统。
在这里插入图片描述

  1. Boot Block是启动块,存在每个分区的开头,备份与启动相关的文件;
  2. 将剩余的空间继续分组,Block group 0 …… Block group n。管理好Block group 0,其他的也可以管理好,因此我们需要了解Block group 0;
  3. Super Block:保存的是整个文件系统的信息,为什么Super Block不能像Boot Block一样存在与每个分区的开头?
    将Super Block保存在不同的分组中是为了备份,假如某个Super Block损坏,我们可以通过拷贝其他分组的Super Block来修复它。
  4. Linux的文件 = 内容 + 属性。Linux的文件内容和属性是分批存储的。文件属性保存在inode中,inode的大小是128字节,是固定的。一个文件有且仅有一个inode与之对应。inode中存储文件几乎所有的属性,但是文件名并不在inode中存储。文件内容存储在data block块中,不同的文件,文件内容是不同的,大小也不同。
  5. inode为了区分彼此,每一个inode都有自己的ID,我们可以通过指令ls -li 来查询文件对应的inode编号。
    在这里插入图片描述
  6. inode table保存分组内部所有的可用(已经使用 + 没有使用)inode。
  7. Data blocks 保存分组内部所有文件的数据块(保存文件内容)。
  8. inode Bitmap:inode对应的位图结构,统计inode的使用情况,位图中比特位的位置与当前文件对应的inode的位置是一样对应的,比特位为1说明该inode已经被占用,否则表示未被占用(即,可以被使用)。
  9. GDT(group descripteor table):块组描述表,对应分组的宏观的属性信息,inode有多少个,已经使用多少,已经被占用多少个,还剩下多少个。
  10. 查找文件时,统一用的是inode编号。

文件内容放在data blocks中,文件属性保存在inode中,而inode内部有一个数组,保存对应data blocks块的编号,二者就联系起来了。
在这里插入图片描述
如果文件特别大,并不是所有的data blocks都只能存储文件数据,它也要存储其它块的块号,所以一个blocks块会指向其它多个blocks来存储文件数据(这样能存更多)。
在这里插入图片描述

2.对文件进行操作

  • 创建文件:位图的比特位由0置为1,找到其inode table,将文件属性填进去,文件的数据写入data blocks中,建立inode和block之间的映射关系;

  • 查找文件:拿到inode找到对应的inode table,根据inode table 找到对应的数据块,就拿到了文件的内容 + 属性;

  • 删除文件:删除文件只需要找到inode在inode bitmap中的比特位,然后将该比特位由1置为0即可。

  • 恢复文件

删除文件并不需要将文件的数据和内容情况,只需要将对应文件的inode在inode bitmap中的比特位 置为0即可(即使不将它们清空也不会影响新文件的存储,因为新文件的数据会直接将原数据覆盖掉)。因此,在删除文件后是可以及时将文件恢复的,恢复文件只需要找到inode的编号,然后把inode bitmap里对应的比特位由0置为1,再去inode table对应映射表,将blosk bitmap由0置为1即可。
如果在Linux中误删一个文件,还是可以恢复的,前提是文件的inode和data block没有被占用,因此当误删一个文件时最好的做法是什么也不做。
在windows下,删除文件到回收站,实际上是将文件转移到回收站的目录而已,只有在回收站中删除才是真的删除。

为什么我们在目录中查找文件时,用的是文件名而不是inode?
因为任何一个文件都是创建在目录下的(注意,同一目录下不能出现相同文件名的两个文件),目录也是一个文件,也有自己的inode,以及data block。目录的数据块(data block)中存储的是当前目录下的文件的文件名与文件的inode的对应关系(这也是为啥inode中不保存文件名)。
新增文件要向当前目录的内容(data block)中写文件名与inode的映射关系,所以当我们在一个目录下新增文件时,必须要有对目录的写权限
罗列当前目录的文件,要有对目录的读权限,想知道目录中的文件,需要根据文件名找到inode,再读取该文件的属性,读目录内容是拿到文件名,因此目录必须要有读权限

三、软硬链接

1.软链接

创建软链接:

ln -s myfile.txt soft_file.link

文件myfile.txt

在这里插入图片描述
在这里插入图片描述
文件soft_file.link
在这里插入图片描述

inode

可以从上图中看到,soft_file.link是具有自己独立的inode,因此它是一个独立的文件,具有自己独立的内容。
所谓的软链接标定文件,它并不是用文件的inode来标记。看这个现象:我们删除myfile.txt然后再去cat soft_file.link:
在这里插入图片描述
软链接并没有用目标文件对应的inode,而是用目标文件的文件名,软链接的数据块中保存的是指向目标文件的路径,当目标文件被删除时,软链接也就失效了。

删除软链接:

  1. rm
rm -f soft_file.link//和删除普通文件一样
  1. ulink
ulink soft_file.link//删除链接

软链接的作用:

软链接就类似于windows下的快捷方式(桌面的软件图标就是该软件exe的快捷方式,软件实际上的存储位置并不在桌面,我们可以通过快捷方式直接去执行该exe文件)。
执行路径非常深,导致路径非常长不方便记忆,因此我们可以通过软链接来访问文件,这样就不用每次都输入长长的路径来访问文件。
在这里插入图片描述

2.硬链接

创建硬链接:

ln myfile.txt hard_file.link

在这里插入图片描述

inode

可以发现,硬链接没有独立的inode,它的inode是目标文件的inode,因此它不是一个独立的文件。

硬链接的作用?
当硬链接的其中一个文件的大小和内容发生变化,那么它对应的目标文件以及所有目标文件的硬链接都会一起发生改变。硬链接没有创建新的文件,它没有独立的inode、属性、内容。它用的全部是目标文件的inode和内容。

创建硬链接的本质就是在指定的路径下,新增文件名和inode的映射关系

在这里插入图片描述
一个inode可能会被多个文件名所映射,为了方便管理,inode有一个计数器,count的引用计数,将引用计数称为硬链接数:
在这里插入图片描述
这也是为什么我们发现数字由1变为2了,此时inode被两个文件名所指,因此硬链接数变为2。
在这里插入图片描述

删除硬链接

如果把硬链接的目标文件删除,目标文件:
在这里插入图片描述
inode的引用计数变为1,即去掉了一组映射关系。
只有当文件的硬链接数变为0时,该文件才是真的被删除了

硬链接的作用

  1. 为啥创建一个普通文件时,硬链接数是1?
    因为,普通文件本身就有一个文件名和inode对应(只要创建文件,就有一个inode的映射关系)。
  2. 为啥创建一个目录,它的硬链接数是2?
    因为目录于它自己的inode就是一组1映射关系;其次,目录内部的'.''.'也表示当前目录,它也是文件名)和inode也是一组映射,所以硬链接数是2。
    在这里插入图片描述

特别的,在当前目录下创建再一个目录,当前目录的硬链接数会变为3,因为当前目录下创建的哪个目录中默认的文件名'..''..'表示上一层目录,它也是文件名)和inode也是一组映射。
在这里插入图片描述
上面的是2,原因是在创建dir2之前打开的,因此没有及时更新,我们看最下面的结果(硬链接数为3)即可。

目录不能自定义建立硬链接

我们发现Linux不允许普通用户给目录建立硬链接。
在这里插入图片描述
这是为什么呢?
我们知道,Linux默认会给目录建立两个硬链接:'.''..'
假如,我们是root(超级用户),系统允许超级用户给目录创建硬链接。我们给根目录创建硬链接,新创建的硬链接的文件名从根目录开始查找,查找到的硬链接就是根目录,此时就造成了递归式查找(环形查找),导致软件无法正常进行查找。因此不允许普通用户给目录建立硬链接。


总结

以上就是今天要讲的内容,本文介绍了磁盘的三种结构、文件系统与inode以及软硬链接的相关概念。本文作者目前也是正在学习Linux相关的知识,如果文章中的内容有错误或者不严谨的部分,欢迎大家在评论区指出,也欢迎大家在评论区提问、交流。
最后,如果本篇文章对你有所启发的话,希望可以多多支持作者,谢谢大家!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/607185.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能python:Python另存为对话框:如何在Python中创建一个另存为对话框

Python 另存为对话框:如何在Python中创建一个另存为对话框 如果你是一名 Python 开发者,你可能会常常需要为你的应用程序添加一个另存为对话框。这个对话框使用户可以将他们的数据保存为一个新的文件,而不是覆盖原始文件。然而,很…

【JavaEE】Tomcat-Servelet第一个helloworld程序

Tomcat & Servelet第一个程序helloworld! 文章目录 JavaEE & Tomcat & 第一个Servelet程序1. HTTP服务器 - Tomcat1.1 Tomcat的目录结构:1.2 启动Tomcat1.3 Tomcat的优点 2. Servelet框架2.1 创建Maven项目2.2 引入依赖2.3 创建目录2.4 写代…

【Java】wait和notify方法

wait方法wait()和join()的区别wait()和sleep()的区别notify()和notifyAll()实例 wait()和notify()方法都是Object类中的方法。由于每个类都会继承Object类,所以每个对象中都会包含这些方法。 wait方法 wait() 是让线程等待一段时间,死等。对应到线程的…

Linux账号管理与ACL权限设定(一)

Linux的账号与群组 Linux系统中,关于账号和群组,实际记录的是UID和GID的数字; 关于账号有两个非常重要的文件:/etc/passwd 和 /etc/shadow ; /etc/passwd 文件结构: 账号名称:密码&#xff…

chatgpt赋能python:Python中另起一行输出的方法

Python中另起一行输出的方法 在Python编程中,我们需要经常输出内容到控制台或者文件中。而有时候,我们可能需要将输出的内容另起一行来符合排版或格式要求。这篇文章将介绍Python中另起一行输出的方法。 使用print函数 Python中最简单的输出方法就是使…

阵列信号处理笔记(1):预备知识、阵列流形、波数-频率响应

阵列信号处理笔记(1) 文章目录 阵列信号处理笔记(1)预备知识从延时到阵列流形矢量频率波数响应 预备知识 如图所示的球坐标系中,任意一阵元的位置可以用 ( r , ϕ , θ ) (r,\phi,\theta) (r,ϕ,θ)唯一表示&#xff…

前端045_单点登录SSO_实现流程

单点登录SSO_实现流程 1、背景2、基于同域下 Cookie 实现 SSO1、背景 在企业发展初期,企业使用的系统很少,通常一个或者两个,每个系统都有自己的登录模块,运营人员每天用自己的账号登录,很方便。 但随着企业的发展,用到的系统随之增多,运营人员在操作不同的系统时,需要…

Linux命令(28)之locate

Linux命令之locate 1.locate介绍 linux命令locate用于查找文件所在位置,与which、whereis命令类似,locate命令将会在预先建立好的档案数据库中查询文件。 locate档案数据库路径:/var/lib/mlocate locate档案数据库名称:mlocat…

SpringBoot之Transactional事务

目录 一、事务管理方式二、事务提交方式三、事务隔离级别四、事务传播行为1、Propagation.REQUIRED2、Propagation.SUPPORTS3、Propagation.MANDATORY4、Propagation.REQUIRES_NEW5、Propagation.NOT_SUPPORTED6、Propagation.NEVER7、Propagation.NESTED 五、事务回滚六、只读…

前后端分离项目之登录页面(前后端请求、响应和连接数据库)

目录 一、前端登录发起请求 二、后端请求接收 三、连接数据库 四、后端响应 五、前端处理 六、在前端验证用户是否登录 七、web会话跟踪 八、请求拦截器和响应拦截器 本文Vue-cli前端项目基于文章: Vue-cli搭建项目(包含Node.js安装和ElementUI安装)_小俱的…

2. requests.get()函数访问网页(小白入门)

2. requests.get()函数访问网页(小白入门) 文章目录 2. requests.get()函数访问网页(小白入门)1. 人工访问网页2. 爬虫第一步:发起网络请求3. requests库的安装4. requests.get()函数:发送网络请求5. 代码解析1. 导入库的语法2. 指定网址3. 发送请求4. 输…

chatgpt赋能python:Python取消撤销——让你的代码更加高效

Python取消撤销——让你的代码更加高效 在Python编程的过程中,经常会出现需要撤销操作的场景。但是,在一些复杂的代码编辑器中,常规的CtrlZ撤销操作可能无法满足你对代码精度的要求。为此,Python取消撤销就应运而生。 Python取消…

多变量系统的最小二乘辨识问题的推导以及matlab仿真

1.单输入单输出情况的推导;2.两输入两输出情况的推导,并进行matlab仿真以及完成仿真报告。 多变量系统的最小二乘辨识问题是确定一个线性多输入多输出(MIMO)系统的未知参数,使得该系统能够以最佳方式近似给定输入和输出之间的关系。在本例中,我们将展示单输入单输出(SIS…

软件外包开发的测试用例

软件测试用例是一组详细的步骤、输入数据、预期结果和实际结果,用于验证软件是否满足特定需求或功能。编写测试用例的目的是确保软件的质量和性能。今天和大家分享编写软件测试用例的一般步骤,希望对大家有所帮助。北京木奇移动技术有限公司,…

解决record on line 2: wrong number of fields

背景 基于"encoding/csv"库解析。 共解析多个文档,只有这一个解析有问题,所用代码一致,进行比较后 发现该文档和其它文档不同,其它文档是第一行就是列名,下面都是数据; 而这个文档前两行有数据且…

k8s部署Elasticsearch集群+Kibana方案--开启X-Pack 安全认证

前言 本文中使用StatefulSet 方式部署 Elasticsearch 集群,并且开启X-Pack 安全认证,存储使用的是NFS,属于一个初学者自己探索的方案,如果有比较好的方案,还请不吝评论赐教。 版本说明: Kubernetes v1.25…

微信小程序uniapp医患管理系统预约挂号就诊处方满意评价系统

从系统开发环境、系统目标、设计流程、功能设计等几个方面对系统进行了系统设计。开发出本医患关系管理系统,主要实现了管理员后端;首页、个人中心、用户管理、医生管理、医生信息管理、患者信息管理、预约就诊管理、就诊信息管理、投诉管理、投诉反馈管…

【走进Linux的世界】Linux---基本指令(2)

个人主页:平行线也会相交 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【Linux专栏】🎈 本专栏旨在分享学习Linux的一点学习心得,欢迎大家在评论区讨论💌 目录 ls *man指令小…

redis缓存穿透、缓存雪崩 、缓存击穿

一、缓存穿透、缓存雪崩 、缓存击穿 摘自尚硅谷文档 1、缓存穿透 缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中,将去查询数据库,但是数 据库也无此记录,我们没有将这次查询的 null 写入缓存,这将导致这个…

Spin加载中(antd-design组件库)loading效果简单使用

1.Spin加载中 用于页面和区块的加载中状态。 2.何时使用 页面局部处于等待异步数据或正在渲染过程时,合适的加载动效会有效缓解用户的焦虑。 组件代码来自: 加载中 Spin - Ant Design 3.本地验证前的准备 参考文章【react项目antd组件-demo:hello-world_…