操作系统:浅谈文件系统

news2024/11/26 22:28:30

目录

1.理解文件系统

1.1.从磁盘开始的抽象存储结构

​编辑

1.2.操作系统下的文件管理

1.2.1.知识储备

1.2.2.存储文件的属性

1.2.3.存储文件的内容

1.2.4.如何新建文件

1.2.5.如何理解目录 

1.2.6.如何找到某一个文件

1.3.操作系统如何打开文件 

2.软硬链接


我们知道文件可以分为:已被打开文件(被进程加载) 和 未被打开文件(在磁盘中保存)这两种文件,而我们对文件的学习也不能只局限于 对被进程打开的文件,因为大部分文件都不是被打开的,而是在磁盘中。这就引申到了操作系统是如何管理未被打开文件,并如何将他们从磁盘中加载到内存,并被进程调用的呢?这就是我们接下来要讲的文件系统的知识了

1.理解文件系统

我们知道文件未被打开时是存储在磁盘这个硬件中,当我们研究文件在磁盘中存储的问题,再结合操作系统的本质就是不断地抽象出数据结构,再连接这些结构。我们学习的核心就是了解操作系统是如何在磁盘中对文件进行增删查改的!

1.1.从磁盘开始的抽象存储结构

如图为磁盘的物理结构和俯视图

从这里我们能够知道:

  • 磁盘俯视来看就是一个圆,而这个圆中会截取一定宽度的圆环称为一个磁道,而这个磁道再均分成一块一块的扇区
  • 磁盘存储时是以“块”为单位的(从扇区体现),扇区是磁盘进行IO读写的最小基本单元,一般是512字节
  • 对于磁盘来说,通过转换“南北极”来实现数据0,1的写入

接着我们来谈谈磁盘是如何定位数据到文件的呢

这里我们就知道了,后续操作系统进行软硬件连接时需要考虑CHS这三个数据!!!

值得说的是:我们通过读写 磁头的编号 就能找到对应的磁盘,再通过 磁头的位置 找到磁道,再结合 磁盘转到的位置 我们就能够定位到任何一个扇区

讲完宏观的结构,接下来我们抽象出一段圆环

接着我们对于这个块的研究等价于对这个圆环(磁盘的一段磁道,若干个扇区)的研究,同时这个抽象图又和我们平常使用的数组这个结构十分类似,那么最终对磁盘的研究就可以从数组这个数据结构作为载体出发了。

做一道数学题

这个也就是CHS定位法的核心,这样子我们通过计算就验证了可以通过数组这个结构在磁盘中抽象出这么一个文件存储的载体。有兴趣可以写一下这个查找程序,so easy的

1.2.操作系统下的文件管理

1.2.1.知识储备

操作系统按照扇区为单位进行存取,也可以基于文件系统按照文件块为单位进行存取,因为一个扇区的大小为512个字节,由于大小依然很小,可能会存在多次的IO调用,浪费系统资源,实际上操作系统定义一个文件块为8个扇区,大小为4096字节,略大于4kb(后面我们统一认为大小为4kb)

实际使用时,我们通过LBA转化成CHS地址,进而定位写入磁盘,在底层对磁盘的写入,变成了在操作系统层面上对一个一个 文件块 的数组的增删查改

注意:磁盘中一个块对应一个扇区,操作系统中一个文件块对应8个扇区 


介绍完了一些基本知识,我们来看看操作系统是如何进行文件管理的!!!

如图:操作系统为了便于管理,在自己内部将对应磁盘大小分为若干个区,再把区划分为组,加下来通过抽象组这个载体来管理文件块这个基本单位。

接下来我们开始学习如何进行 块组 的管理!

先介绍一下概念

  • Boot Block:启动块,作为分区的头,包含磁盘的信息,和操作系统的启动信息
  • Block group:作为管理文件块的载体

  • Super Block:存放文件系统本身的结构信息。记录的信息主要有:bolck 和 inode的总量, 未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的 时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个 文件系统结构就被破坏了

不一定每个块组都有,一般是若干个块组共用一个,管理整个分区,作为操作系统对分区的管理描述的结构体对象,一个分区多个保存防止系统丢失数据


  • inode Table:存放文件属性 如 文件大小,所有者,最近修改时间等

实际上就是存放inode的结构体数组

  • inode Bitmap:每个bit表示一个inode编号是否空闲可用。

用比特位的0、1表示某一个inode编号是否被使用,一个文件块4096字节,而存放32000个inode编号的一个位图大小4KB(4000字节),所以一个文件块能通过位图表示inode编号。

  • Block Bitmap:记录Data Block中哪个数据块已经被占用,哪个数据块没 有被占用

  • Group Descriptor Table:块组描述符,描述块组属性信息,管理一个块组
  • Data Block:存放文件内容

我们知道 文件 = 内容 + 属性,在我们写入文件内容前,需要先写入文件管理数据给磁盘,例如磁盘进行分区后,需要记录这个分区的相关数据再进行文件的内容的写入。也就是块组的引入本质上是为了解决文件内容和属性存储问题。

文件的内容和属性一般是分开存储的,存在块组的不同区域


1.2.2.存储文件的属性

往Linux系统中输入指令 ls -li 我们发现 最前面会有一个数字,这个数字叫做 inode 编号

  • 一般情况下,一个文件只有一个inode,基本上每个文件都有一个inode。
  • 在不同的分区中,inode的数据是唯一的,识别文件只与inode有关
  • inode是用来保存文件的属性,本质上是一个结构体
  • inode中存储的文件属性的种类是固定的

 注意inode不等于inode编号,并且大小固定为128字节

struct inode
{
    // 文件大小 权限 拥有者...

    // inode编号
    // Block block[15]
}

在inode Table中,inode编号便于通过相对位置来找到文件,本质上就是一个存储inode的数据结构

struct inode inode_table[N]    // 可以视为inode结构体数组

1.2.3.存储文件的内容

Data Block是一个以4KB为单位的一块巨大的文件内容存储区,存放整个块组所有文件的内容,在这个区域中我们也是通过编号来进行访问的。存储规则是:通过Block Bitmap查找哪一个数据块没有被占用,然后存储数据进去,接着通过inode结构体中的block数组中存放索引下标(映射),并向这些数组中存放文件内容。

实际操作系统中,0-12下标的数据块是直接映射进数据库保存文件的内容,13间接映射,里面保存更多的 块列表 来进行二次索引,三次索引.......这样实现大文件存放在若干个4KB中保存 

当一个文件特别大时,会在多个块组中存储,实现跨组访问,inode编号在分区里不变即可

1.2.4.如何新建文件

核心就是查询两个位图,找到两个数据,进而实现文件的搭建

  • 先查inode Bitmap查询位图,找到最近的一个没有被使用的比特位由0置为1,然后查询遍历位图时的偏移量,加载进inode,设置文件属性和编号
  • 接着从block Bitmap里面找到一个位置,同理0置为1,记录偏移量,然后从inode中的Block block找到对应的block然后写入文件的内容

那我们如何删除呢?

我们在新建文件时,就已经知道文件的inode编号,我们可以找到对应的位图中的比特位,由1改为0,同理把占用的块也由1置0,未被释放的资源后续可能被其他文件覆盖。

1.2.5.如何理解目录 

实际使用计算机时,面向用户的是文件名而不是inode,也就是inode是实现内核与文件的映射,又因为Linux中一切皆文件。那么我们知道 目录 本质上也是文件,也有自己的inode结构体,那么目录的块存放的数据是什么呢?

目录的块中存放着 文件名 和 inode的映射关系(k-v关系),也就是我们通过文件名可以找到目录下文件的inode进而连接整个文件管理体系,所以同一个目录下不允许存在同名文件。又inode在该分区中独一无二,所以文件名和inode互为k-v关系。

讲到这里,顺便提一下:文件名不是inode结构体的内容,而是目录的内容。

1.2.6.如何找到某一个文件

  1. 找到文件的上一级目录,在通过访问文件的block存储的数据找到文件名和inode的映射关系这样就能找到 inode和inode编号
  2. 接着通过inode编号找到哪个组,进而访问到哪个块,然后获取文件的属性、内容

那么如何找到上一级的目录呢(也就是找到他的inode)?那上一级的目录的目录如何找到呢?也就是回归到 我们需要找到根目录的inode。找到文件需要从根目录开始逐层查找到该文件的上一级文件。查找时我们也是借助进程,那么就会有cwd,进行会记录当前的路径


关于查找不同分区下的文件,因为Linux在进行磁盘格式化分区后,会进行挂载,并且可以通过文件的路径来找到挂载对应的分区,也就是我们可以通过文件路径来确定在哪个分区。

1.3.操作系统如何打开文件 

  • 未被打开前,文件存在于磁盘,打开时,操作系统创建进程来打开这个文件
  • 进程拥有自己的cwd通过路径来定位在磁盘的哪一个分区,接着顺着路径向下找
  • 找到创建inode结构体,实现了文件属性的写入
  • 接着通过inode编号找到Data Block,就可以写入文件的内容
  • 将缓冲区的内容拷贝进文件的对应Block block数组对应的数据块

2.软硬链接

建立软连接的指令

ln -s 待链接文件名 软连接文件名
// 例如
ln -s log.txt log.sort.link

创建软连接时,log.sort.link具有自己的inode,也就是创建的软连接是一个新文件 

建立硬链接的指令

ln 待链接文件名 硬链接文件名
// 例如
ln file.txt file.hard.link

file.hard.link没有自己的inode(和源文件一致),也就是硬链接不是独立的文件

 我们可以通过 ls -li查看inode、权限、硬链接数、拥有者....... 

注意:可以给目录建立软连接,不允许给目录建立硬链接。

 


软连接

在Windows中软连接的体现就是:文件的快捷方式,软连接的本质就是指向源文件的一个副本文件。

软连接形成一个副本文件便于用户使用,也防止对源文件进行非法的操作


硬链接

硬链接不是一个独立的文件,本质是指定目录内部的一组关于 文件名 和 inode 的映射关系!

我们知道文件被删除的本质:没有了当前文件名和inode的映射关系,在文件系统层面,inode结构体中定义了一个引用计数变量,标明有几个文件名的映射关系,也就是有几个硬链接

当我们分别创建一个新文件和新的目录时我们发现,硬链接数分别为1和2,因为普通文件只有一组文件名和inode的映射关系,目录文件有两组映射关系。

因为我们创建目录时,目录内会自动创建两个文件 . 和 .. 文件,其中 . 文件为指向这个目录的映射,而目录名本身跟自己的inode也有一组映射关系,所以是两个,那么假如我们在这个目录下在创建一个目录后原目录下的硬链接数变为几了呢?(可以通过ls -lia指令查看)

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

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

相关文章

智慧开发平台免!费!申请试用

原创 F学社 F学社 2024-04-01 17:13 江苏 扫描二维码即可申请试用 01 智慧开发平台简介 F1 WIFI智慧教育平台是可支持线上线下联动的基于FPGA的口袋式数字系统学习平台。其采用了AMD、Altera、安路、高云等国外国内主流公司的FPGA进行数字系统方向的教学实验设计&#xff0c…

《云原生安全攻防》-- K8s集群安全风险分析

在这个数字化快速发展的年代,云原生安全变得越来越重要。我明白对于很多朋友来说,这是一个既新奇又复杂的领域。因此,我整合了以往的专业积累,精心打造了一个专门讲解云原生安全的系列课程,目的是能给大家带来有价值的…

9Proxy,跨境电商一站式解决方案

文章目录 跨境电商什么是跨境电商跨境电商的机遇跨境电商技术支撑 海外代理IP什么是海外代理IP海外代理IP的作用如何选择海外代理IP 9Proxy9Proxy的优势9Proxy的解决方案价格汇总搜索引擎优化市场调查多重核算数据抓取广告技术 价格上手体验注册登录下载安装数据采集 总结福利 …

【数据结构】——二叉树堆的实现

大佬们点点关注,点点赞?! 前言 在上篇博客中我们已经介绍了树和二叉树的相关概念,相信大家都已经清楚了树和二叉树的基本思想,下面我们就来着重看看二叉树堆的实现。 在看堆的实现,我们先看看二叉树的顺…

Linux 安装部署高性能缓存服务redis

Linux 系统安装Redis 5 注意事项: 下载Redis 文件包,并上传至linux服务上解压 tar -zxvf redis.tar安装: 编译 make PREFIX/usr/local/redis install配置: redis.conf daemonize yes bind 127.0.0.1 192.168.1.221 supervised…

坚持刷题|分发饼干

文章目录 题目思路代码实现实现总结主要步骤时间复杂度 扩展问题 Hello,大家好,我是阿月。坚持刷题,老年痴呆追不上我,今天刷第一个贪心算法:分发饼干 题目 455.分发饼干 思路 要解决这个问题,可以使用…

解锁AI提示工程新纪元:你的提问是关键!

文章目录 一、AI的潜力:无尽的宝藏等待解锁二、提问的艺术:挖掘AI潜力的关键三、AI的回应:超越预期的答案与启示四、提问的力量:推动AI不断进步与发展五、用提问开启与AI的智慧对话《向AI提问的艺术:提示工程入门与应用…

C++中的面向对象到底是什么

C中的面向对象到底是什么 对象嘛,就和大家都有的对象一样,两只眼睛、一个嘴巴、两条腿…… 对不起跑题了,C的面向对象中的对象可不是显示中的对象哦,但是有一些相似之处,有对象的同学可以参考着去学习C面向对象的概念…

niushop单商户V5多店版源码分享三端uniapp打包方法包括PC端_小程序或h5端打包_收银端打包_APP端打包_商户端

目前多店版有四端uniapp,包括PC端uniapp,商家端uniapp,收银端uniapp,门店手机端uniapp,下面我总结下这些端的打包流程希望能帮助到大家,需要交流的可以看我昵称或者点我头像关注我分享代码和教程 一.niush…

原创歌曲分享平台的设计与实现|Springboot+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)

本项目包含可运行源码数据库LW,文末可获取本项目的所有资料。 推荐阅读300套最新项目持续更新中..... 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含ja…

帝国CMS十合一源码/字典/成语/古诗词/二十四节气/英语单词/百家姓/范文文库/词语等

帝国CMS十合一源码/字典/成语/古诗词/二十四节气/英语单词/百家姓/范文文库/词语等 功能包含: 成语大全 二十四节气 英语单词 古诗词 近反义词 词语造句 汉语字典 英文缩写 百家姓 范文文库 文件目录:1个数据库 1个系统源码 1个伪静态规则 安装方式:把1.2G的…

数据结构:非比较排序

非比较排序都具有很大的局限性,包括技术排序,基数排序,桶排序等 计数排序 时间复杂度:O(N) 空间复杂度:O(range) 适用范围 数据的范围集中的数组进行排序,不适合数据分散的数组 方法 统计每个数据出现的次数为n 建立一个相同大小的数组,将每个数据都初始化为0 然后遍历…

在Windows的Docker上部署Mysql服务

在我们做一些和数据库相关的测试时,往往需要快速部署一个数据库作为数据源。如果开发环境是Windows,且开发的代码不依赖于系统,即不用在linux上做开发,则可以将全套环境都部署在Windows上。 本地安装数据库会污染操作系统环境&…

面试题 之 vue

1.vue里怎样实现双向数据绑定? Viewmodel 中的Domlisteners 工具会帮我们检测页面上Dom元素的变化,如果有变化,则更改Model中的数据,更新model中的数据时,数据事件绑定工具会帮我们更新页面中的Dom元素 2.Vue的响应式原…

Autosar-诊断配置详解(免费)-1

1DcM功能简介 诊断通信管理(Diagnostic Communication Manager, DCM)模块作为AutoSar诊断模块的重要组成部分,主要负责诊断数据流和管理诊断状态,包括诊断会话、安全状态及诊断服务分配等。 主要功能贯穿汽车的开发生产及售后等过程,如开发过…

零基础入门转录组数据分析——DESeq2差异分析

零基础入门转录组数据分析——DESeq2差异分析 目录 零基础入门转录组数据分析——DESeq2差异分析1. 转录组分析基础知识2. DESeq2差异分析(Rstudio)3. 结语 1. 转录组分析基础知识 1.1 什么是转录组? 转录组(transcriptome&#…

MATLAB近红外光谱分析技术应用

郁磊副教授,主要从事MATLAB编程、机器学习与数据挖掘、数据可视化和软件开发、生理系统建模与仿真、生物医学信号处理,具有丰富的实战应用经验,主编《MATLAB智能算法30个案例分析》、《MATLAB神经网络43个案例分析》相关著作。已发表多篇高水…

STC8H8K64U 学习笔记 - PWM

STC8H8K64U 学习笔记 - PWM 环境说明引脚说明 PWM呼吸灯震动马达 乐谱 环境说明 该内容仅针对我自己学习的开发板做的笔记,在实际开发中需要针对目标电路板的原理图进行针对性研究。 芯片:STC8H8K64U烧录软件:stc-isp-v6.92G编码工具&#xf…

springJPA如果利用注解的方式 进行多表关联操作

前言:上一篇我写了个用JPA的Specification这个接口怎么做条件查询并且进行分页的,想学的自己去找一下 地址:springJPA动态分页 今天我们来写个 利用jpa的Query注解实现多表联合查询的demo 注意: 不建议在实际项目中用这玩意. 因为: 1. 用Query写的sql 可读性极差,给后期维护这…

C++读取bin二进制文件

C读取bin二进制文件 在C中,可以使用文件输入/输出流来进行二进制文件的读写操作,方便数据的保存和读写。 //C读取bin二进制文件 int read_bin() {std::ifstream file("data_100.bin", std::ios::in | std::ios::binary);if (file) {// 按照二…