Linux基础IO【深入理解文件系统】

news2024/12/23 5:38:50

✨个人主页: 北 海
🎉所属专栏: Linux学习之旅
🎃操作环境: CentOS 7.6 阿里云远程服务器

成就一亿技术人


文章目录

  • 🌇前言
  • 🏙️正文
    • 1、磁盘文件
    • 2、磁盘概念
      • 2.1、基本结构
      • 2.2、数据存储
    • 3、磁盘信息
      • 3.1、分区意义
      • 3.2、块组信息
    • 4、文件相关操作
      • 4.1、文件创建
      • 4.2、文件访问
      • 4.3、对文件进行增删查改
      • 4.4、文件误删后的解决方案
      • 4.5、大文件存储
  • 🌆总结


🌇前言

文件分为 内存文件磁盘文件内存文件 相关知识前面已经介绍过了,接下来谈谈 磁盘文件,这是一个特殊的存在,因为它不属于冯诺依曼体系,而是位于专门的存储设备中,因此 磁盘文件 存在的意义是将文件更好的存储起来,以便后续对文件进行访问。在高效存储 磁盘文件 这件事上,前辈们研究出了十分巧妙的管理手段及操作方法,而这些手段和方法共同构成了我们今天所谈的 文件系统

文件系统

注: 本文主要介绍对象为机械硬盘存储模式及 EXT 文件系统


🏙️正文

1、磁盘文件

在计算机中,没有被打开的文件都是静静的躺在外存(磁盘)中,当需要对文件进行操作时,会通过 inode 对文件进行访问

通过以下指令查看当前目录中文件的详细信息及 inode

ll -i

inode
如同 pid 与进程的唯一对应性一样,inode 与文件也是唯一对应的(未被硬链接的情况下),可以通过 inode 访问文件在磁盘中的详细信息

磁盘文件是如何进行管理的?

  • 磁盘文件的管理类似于菜鸟驿站,其中的包裹就像待访问的文件,而 inode 就是取件码
  • 得益于这种规范化的存储模式,我们可以做到对文件的快速定位、快速读取和快速写入

菜鸟驿站
以上的 “管理” 只是抽象概念,具体动作还得对磁盘结构学习后,才能更好的理解


2、磁盘概念

现在市面上的磁盘主要分为 机械硬盘固态硬盘,前者读取速度慢,但便宜、稳定;后者读取速度快,但价格高昂且数据易损,两者各有其应用场景,本文主要介绍的是 机械硬盘

1
磁盘2

2.1、基本结构

机械硬盘是我们电脑中的唯一一个机械设备,并且它还是一个外设,根据 冯诺依曼体系结构机械硬盘 在速度上远远慢于 CPU内存

举例机械硬盘有多慢

  • 假设 CPU 运行速度是纳秒级,那么内存就是微秒级,而机械硬盘只不是是毫秒级

为何 机械硬盘 如此慢?这与它的结构有很大关系

机械硬盘 的结构主要包括以下几种:

  • 盘片:一片两面,每一面都可以存储数据,有一摞盘片
  • 磁头:一面配备一个磁头,专门用于读取盘面中的数据
  • 主轴:用于控制整块盘的转动
  • 音圈马达:控制磁头的进退
  • 磁头臂:链接磁头与音圈马达
  • 伺服电路板:控制读取数据的流向及各种结构的运行
  • ……

注意: 多个盘片、多个磁头都是共进退的

机械设备 控制是需要时间的,因此导致 机械硬盘 读写数据速度相对于 CPU内存 来说比较慢
机械硬盘的结构
关于 机械硬盘 更为详细的内部结构,可以查看这篇文章 《机械硬盘内部是什么结构?》

真实的盘片
盘片

2.2、数据存储

总所周知,数据是以 01 的方式进行存储的,常见的存储介质有:强信号与弱信号高电平与低电平波峰与波谷南极与北极 等,而盘面上比较适合的是 南极与北极

图解
当磁头移动到指定位置时

  • 向磁盘写入数据:N->S
  • 删除磁盘中的数据:S->N

磁盘中读写的本质:更改基本元素的南北极、读取南北极

注意: 磁头并非与盘面进行直接接触,而是以 15 纳米的超低距离进行磁场更改

这个距离相当于一架波音747距离地面1米进行超低空飞行,所以如果磁头制作工艺不够精湛,可能会导致磁头在写入/读取数据时,与盘面发生摩擦(高速旋转)发热,从而导致磁场消失,该扇区失效,数据丢失

波音747

机械硬盘 不能在其运行时随意移动,因为角度的偏转也有可能导致发生摩擦,造成数据丢失,更不能用力拍打 机械硬盘

关于 机械硬盘 写入数据时的工作原理可以观看以下视频

机械硬盘工作原理

在盘面设计上,一个盘面被切割若干个扇区,单个扇区大小为 512 字节(或者 4 kb),这些扇区用来存储数据,同一半径中的所有扇区组成扇面;而半径相同的扇区组成磁道(柱面)

我们可以先根据磁头(head)确定盘面,再根据半径定位磁道(柱面 cylinder),最后根据块号确定扇区(sector)

  • 这种寻址方法称为 CHS 定位法,是机械设备查找具体扇区时的方法

图解
读取数据
文件(数据+属性)在存储时,占用一个或多个扇区进行数据存储

图解
虽然 CHS 定位法很妙,但它太依赖于具体硬件信息了,假设其中的硬件参数有所不同,那么 OS 就得使用另一套 CHS 定位法,于是为了做到 解耦OS 使用的并非 CHS 定位法进行文件定位,而是采用 LBA 逻辑地址块进行寻址

  • 将盘面分割为多个线性分区,通过下标 N 计算出 CHS 地址,然后进行文件访问

将磁道拉长,会得到一串线性空间(数组),其中的每个单位(扇区)为 512 字节(或者 4 kb

图解
现在 OS 想访问具体的扇区时,只需通过 起始扇区的地址 + 偏移量 就可以获取 LBA 地址,然后通过特定手段转为 CHS 地址,交给外设进行访问即可 LBA和CHS转换

因此对于外设中文件的管理,经过 先描述,再组织 后,变成了对数组的管理,这个数据就是 task_struct 中的 struct block

最后我们就能理解为什么 IO 的基本单位是 4 kb 了,因为直接读取一个数据块(4 kb),这样可以提高 IO 效率(内存对齐)


3、磁盘信息

一般电脑中会存在多个分区,比如 C盘D盘,那么为何需要存在这些分区呢?

3.1、分区意义

磁盘空间是巨大的,如果不加以划分,会导致 OS 的管理成本提高,对应到现实生活中,学校需要将不同专业的学生及老师分为不同学院,比如管理学院、信息工程学院等,分院后的好处不言而喻,最重要的是上层管理者更好的调用管理资源,这种思想称为 分治思想

在文件系统中,OS 先将整个大文件系统分为不同的区,存入 struct disk 数组中进行管理

struct disk
{
	struct part[2];
	//……
};

可以通过 ll /dev/vda* -i 查看当前系统中的 分区数详细信息

结果
系统在分区后,需要对区块进行格式化

图解
不同的文件系统在格式化时写入的数据是不同的,这里讨论的是 EXT 文件系统

  • 磁盘分区后,分组、填写系统属性是 OS 做的事

  • 为了使分区能被正常使用,需要对分区进行格式化

  • 分区格式化:OS 向分区写入文件系统的管理属性信息

  • 在具体分区内,还可以细分为 块组

块组 构成的线性空间亦可称为 组线 (代表一个 分区

struct part
{
    struct part group[100];	//分为100个块组
    int lba_start;	//起始与结束位置
    int lba_end;
    //……
}

将现有资源再分配后,可以 最大化利用资源,避免造成浪费及拖慢效率

块组(Block Group)是本文的重点内容

3.2、块组信息

块组 是由 分区 细分出的产物,它与分区的关系如图所示:

图示

其中, Boot Block启动块,大小固定为 1 kb,在每一条 组线 前都有此 块组,它用来 存储分区信息和系统启动,属于被保护的内容,不允许用户私自修改

至于其他 块组,它们有着统一的格式,具体内容如图所示:
图解
其中一个文件对应一个 inode,而 inode 中存储了该文件的所有属性,包括所使用的数组块信息,因为文件很多,所以需要 先描述,再组织,即通过 inode Tableinode 进行管理

注意:

  • inode 属性中并不包含文件名,文件名只是给用户用的
  • 目录文件也有 inode,目录中的数据块保存的是该目录下的 文件名inode 编号对应的映射关系,而且在此目录内,文件名和 inode 互为 key
  • inode 确定分组,inode 值只在一个分区内有效,不能跨分区

4、文件相关操作

接下来看看文件是如何创建在磁盘中的

4.1、文件创建

创建一个文件的步骤如下:

  1. 申请一个空闲的 inode,将文件信息记录至 inode 属性中
  2. 寻找空闲的数据块(Data block),将数据块信息填入 inode 中的磁盘分布区
  3. 添加文件名至当前目录文件的 Data block 中,同时将文件名和 inode 之中的属性链接起来

注意: 每使用一个 inode 和一个 Data block,需要把它们对应位图中的信息改为已占用

结果

4.2、文件访问

文件创建后,如何根据 inode 访问文件呢?

  • 找到文件的 inode 编号,在目录分组中查找
  • 通过 inodeData block 的映射关系,找到文件的数据块,并加载至内存中

这也就解释了为什么在 file 对象中会存在 inode 信息,因为它与 fd 一样重要

4.3、对文件进行增删查改

文件创建后,如何删除?删除并不是真删除,而是将 inode BitmapBlock Bitmap 中位图信息进行修改即可(只要访问不到,就是删除)

  • 根据文件名找到 inode 编号

  • 再根据 inode 属性中的映射关系,设置 Block Bitmap 对应的比特位,设置为 0 (删内容)

  • 最后根据 inode 编号设置 inode Bitmap 中对应的比特位为 0 (删属性)

将位图信息置为 0 后,创建新文件时,系统可以直接使用

至于文件的查找与修改,通过 inode 修改其内部属性即可

注意: inodeData blcok 可能存在失衡的情况

  • 一直创建空文件,导致 inode 满载,而 Data block 空余很多
  • 不断往同一个文件中写入数据,导致 Data block 被占用,后续创建文件时,inode 无法再分配到 Data block

4.4、文件误删后的解决方案

磁盘中的数据被删除后,还可以再恢复吗?答案是可以的,但不能完全恢复,并且越早断电、送修越好

前面说过,删除并不是真删除,访问不到就行了,所以只要在删除后,根据 inode 找到 Data block,其中的内容没有被覆盖,数据就可以找回来

应急方案:

  • 不要轻举妄动,避免 Data block 被覆盖
  • 通过 inodeinode Bitmap 中的位图置 1,使文件复活,再根据属性进行数据恢复
  • 如果自己不知道 inode,那就尽早断电,送给厂家恢复(专业)

如何避免误删文件?

  • 学习 Windows 中的回收站,删除不是真删除,而是先将文件移入回收站(目录)中,留给用户反悔的时间

4.5、大文件存储

单个数据块大小有限(4 kb),如何做到一个数据块存储大量数据?

答案是 套娃Data block 中存储其他 Data block 信息,此时称为多级索引,可以做到一个数据块中存储大量数据

图解

注:本篇博客中的大部分图片来自 Linux基础IO、学习系统编程No.13【文件系统】 && 学习系统编程No.14【动静态库】 以及互联网


🌆总结

以上就是本次关于 Linux基础IO【深入理解文件系统】的全部内容了,本文理论偏多,重点在于机械硬盘结构及文件系统组成的理解,尤其是 Blcok Group 的学习,这些知识能帮我们能好的理解整个文件系统,明白一个文件是如何被创建、被访问、被加载、被修改的全部过程,并且还能后续软硬链接的学习打下基础

鸣谢 2021dragon 和 今天还要努力 两位大佬提供的博客图片


星辰大海

相关文章推荐

Linux【模拟实现C语言文件流】

Linux基础IO【重定向及缓冲区理解】

Linux基础IO【文件理解与操作】

===============

Linux【模拟实现简易版bash】

Linux进程控制【进程程序替换】

Linux进程控制【创建、终止、等待】

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

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

相关文章

【C++初阶】类与对象:6大默认成员函数------拷贝构造和赋值运算符重载

一.拷贝构造函数 A.概念 拷贝构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对象创建新对象时由编译器自动调用。 B.特性 1. 拷贝构造函数是构造函数的一个重载形式; 2. 拷贝构造函…

shell的基础学习二

文章目录 一、Shell 数组二、Shell 基本运算符三、Shell echo命令四、Shell printf 命令五、Shell test 命令总结 一、Shell 数组 数组中可以存放多个值。Bash Shell 只支持一维数组(不支持多维数组),初始化时不需要定义数组大小&#xff08…

【五一创作】【Simulink】基于FCS-MPC的三相并网逆变器控制(Stateflow)

上次写了一篇【Simulink】基于FCS-MPC的三相并网逆变器控制(Matlab Function),控制部分用 Matlab Function 写的,因实验室一般用 Stateflow,所以这篇把 Matlab Function 改成 Stateflow. 原理 电路原理图:…

如何批量查询快递的签收状态?

如果一次性网购大量快递,我们就得经常进入快递或网购平台查询物流,随时查看快递单号的物流状态。如果快递公司少,查询起来比较容易,但是如果快递公司很多,每次都要人工查询就是一件很麻烦的事情了。今天,小…

数据库相关知识

一.1 数据库 与Sybase不同,一个用户就对应于一个数据库。 create user CBMAIN identified by "sunline" default tablespace CBMAIN_DATA  -- 表空间 temporary tablespace CBMAIN_TEMP; -- 临时表空间 一.2 表空间 表空间由一个或多个物理文件组成&…

js使用splice方法删除数组元素可能导致的问题

splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。 JavaScript 遍历数组并通过 splice 方法删除该数组符合某些条件的元素将会导致哪些问题? 导致的问题 当使用 splice 方法从 …

QT 中的多线程之继承 Thread

文章目录 1. 概述2. UML 类的关系图3. 代码:4. 运行结果及说明5. 结语 1. 概述 任何继承于QThread的线程都是通过继承 QThread 的run函数来实现多线程的,因此,必须重写QThread的run函数,把复杂逻辑写在QThread的run函数中。然后在…

effective c++ item40-44

item40:谨慎的使用多重继承 多重继承带来的符号的歧义性 #include <iostream> #include <vector> using namespace std; class A { public:void f() { cout << "A" << endl; } }; class B { private:void f(); }; class C : public A, publ…

5.5.1哈夫曼树

知识总览&#xff1a; 概念&#xff1a; 结点的权&#xff1a;有某种现实含义的数值&#xff08;如&#xff1a;表示结点的重要性&#xff09; 结点的带权路径长度&#xff1a;从树的根到该结点的路径长度&#xff08;经过的边数&#xff09;与该结点上权值的乘积。 就比如说要…

ETL工具 - Kettle 案例,拉取网络列表数据

一、Kettle 实战案例 上篇文章对 Kettle 的查询、连接、统计、脚本算子进行了介绍&#xff0c;对 Kettle 的大部分算子都应该有了相应的了解&#xff0c;下面我们基于 Kettle 实战案例&#xff0c;拉取 CSDN 博客列表的全部数据&#xff0c;存放至 Excel 文件中。 实验之前先…

NECCS|全国大学生英语竞赛C类|词汇和语法|词汇题|21:03~21:53

词汇题 语法题 情景对话题 目录 一、词汇题 1. 基本词义辨析题 2. 同义词或近义词辨析题 3. 固定搭配 二、常见词组 一、词汇题 1. 基本词义辨析题 appropriate funds 拨款 slum- clearance programme 贫民窟清理计划 reject 拒绝接受&…

DAY 49 tomcat服务配置优化

什么是Tomcat Tomcat是Java 语言开发的&#xff0c;Tomcat 服务器是一个免费的开放源代码的Web应用服务器&#xff0c;是Apache 软件基金会的 Jakarta 项目中的一个核心项目&#xff0c;由Apache、Sun和其他一些公司及人共同开发而成。 Tomcat属于轻量级应用服务器&#xff0…

外卖项目优化-02-

文章目录 瑞吉外卖项目优化-Day02课程内容前言1. MySQL主从复制1.1 介绍1.2 搭建1.2.1 准备工作1.2.2 主库配置1.2.3 从库配置 1.3 测试 2. 读写分离案例2.1 背景介绍2.2 ShardingJDBC介绍2.3 数据库环境2.4 初始工程导入2.5 读写分离配置2.6 测试 3. 项目实现读写分离3.1 数据…

深入解析PyTorch中的基本数据结构:张量的维度、形状和数据类型

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

【LEAP模型】能源环境发展、碳排放建模预测及不确定性分析

本次内容突出与实例结合&#xff0c;紧密结合国家能源统计制度及《省级温室气体排放编制指南》&#xff0c;深入浅出地介绍针对不同级别研究对象时如何根据数据结构、可获取性、研究目的&#xff0c;构建合适的能源生产、转换、消费、温室气体排放&#xff08;以碳排放为主&…

【Spring框架全系列】Spring更简单的读取和存储对象

&#x1f4ec;&#x1f4ec;哈喽&#xff0c;大家好&#xff0c;我是小浪。上篇博客我们介绍了如何创建一个spring项目&#xff0c;并且如何的存、取对象&#xff0c;介绍了相关方法&#xff0c;那么本篇博客将接着上篇博客的内容介绍如何更加简单的读取和存储对象。 &#x1f…

从源码角度看Linux进程组和线程组

1.进程ID 线程组ID&#xff1a; 设置了CLONE_THREAD flag创建的进程(线程&#xff09;同属于同一个线程组&#xff0c;拥有同一个线程组ID(TGID)。pthread_create创建线程的时候&#xff0c;底层通过clone函数实现就指定了CLONE_THREAD参数&#xff0c;即一个进程中的各个线程…

前端搭建猜数字游戏(内附源码)

The sand accumulates to form a pagoda ✨ 写在前面✨ 功能介绍✨ 页面搭建✨ 样式设置✨ 逻辑部分✨ 完整代码 ✨ 写在前面 上周我们实通过前端基础实现了打字通&#xff0c;当然很多伙伴再评论区提出了想法&#xff0c;后续我们会考虑实现的&#xff0c;今天还是继续按照我…

架构设计-数据库篇

大家好&#xff0c;我是易安&#xff01; 之前我们讲过架构设计的一些原则&#xff0c;和架构设计的方法论&#xff0c;今天我们谈谈高性能数据库集群的设计与应用。 读写分离原理 读写分离的基本原理是将数据库读写操作分散到不同的节点上&#xff0c;下面是其基本架构图。 读…

【ansys】project may be corrupted and recovery information is available

一、问题背景 在网上找一个fluent算例打算在自己机器上运行。 打开fluent求解器&#xff0c;因为路径上有中文&#xff0c;在求解计算的时候出错了。 于是我通过任务管理器强制退出fluent和workbench程序&#xff0c;再将项目文件复制到一个没有中文的目录路径中。 重新打开…