Linux文件系统

news2024/12/23 18:10:46

Linux文件系统

文章目录

  • Linux文件系统
    • 1.对文件系统的理解
      • 1.1 文件系统当中的缓冲区
      • 1.2 文件系统当中的inode
      • 1.3 文件属性与文件数据分开存放原理
    • 2.对软硬链接的理解
    • 扩展:对文件三时间的理解

1.对文件系统的理解

1.1 文件系统当中的缓冲区

我们来看看下面这段代码,代码当中分别用了两个C库函数和一个系统接口向显示器输出内容,在代码最后还调用了fork函数

#include <stdio.h>
#include <unistd.h>
int main()
{
	//c
	printf("hello printf\n");
	fputs("hello fputs\n", stdout);
	//system
	write(1, "hello write\n", 12);
	fork();
	return 0;
}

请添加图片描述

运行该程序,我们可以看到printf、fputs和write函数都成功将对应内容输出到了显示器上

但是,当我们将程序的结果重定向到log.txt文件当中后,我们发现文件当中的内容与我们直接打印输出到显示器的内容是不一样的

请添加图片描述

那为什么C库函数打印的内容重定向到文件后就变成了两份,而系统接口打印的内容还是原来的一份呢?

首先我们应该知道的是,缓冲的方式有以下三种:

  1. 无缓冲
  2. 行缓冲 (常见的对显示器进行刷新数据)
  3. 全缓冲 (常见的对磁盘文件写入数据)

上面C库函数打印两份的原因:

  • 当我们直接执行可执行程序,将数据打印到显示器时所采用的就是行缓冲,因为代码当中每句话后面都有\n,所以当我们执行完对应代码后就立即将数据刷新到了显示器上
  • 而当我们将运行结果重定向到log.txt文件时,数据的刷新策略就变为了全缓冲,此时我们使用printf和fputs函数打印的数据都打印到了C语言自带的缓冲区当中,之后当我们使用fork函数创建子进程时,由于进程间具有独立性,而之后当父进程或是子进程对要刷新缓冲区内容时,本质就是对父子进程共享的数据进行了修改,此时就需要对数据进行写时拷贝,至此缓冲区当中的数据就变成了两份,一份父进程的,一份子进程的,所以重定向到log.txt文件当中printf和puts函数打印的数据就有两份。但由于write函数是系统接口,我们可以将write函数看作是无缓冲区的,因此write函数打印的数据就只打印了一份

通过上面的内容,我们有一些问题需要理解:

  1. 这个缓冲区是谁提供的?

    • 实际上这个缓冲区是C语言自带的,如果说这个缓冲区是操作系统提供的,那么printf、fputs和write函数打印的数据重定向到文件后都应该打印两次
  2. 这个缓冲区在哪里?

    • 我们常说printf是将数据打印到stdout里面,而stdout就是一个FILE*的指针,在FILE结构体当中还有一大部分成员是用于记录缓冲区相关的信息的

    • //缓冲区相关
      /* The following pointers correspond to the C++ streambuf protocol. */
      /* Note:  Tk uses the _IO_read_ptr and _IO_read_end fields directly. */
      char* _IO_read_ptr;   /* Current read pointer */
      char* _IO_read_end;   /* End of get area. */
      char* _IO_read_base;  /* Start of putback+get area. */
      char* _IO_write_base; /* Start of put area. */
      char* _IO_write_ptr;  /* Current put pointer. */
      char* _IO_write_end;  /* End of put area. */
      char* _IO_buf_base;   /* Start of reserve area. */
      char* _IO_buf_end;    /* End of reserve area. */
      /* The following fields are used to support backing up and undo. */
      char *_IO_save_base; /* Pointer to start of non-current get area. */
      char *_IO_backup_base;  /* Pointer to first valid character of backup area */
      char *_IO_save_end; /* Pointer to end of non-current get area. */
      
    • 也就是说,这里的缓冲区是由C语言提供,在FILE结构体当中进行维护的,FILE结构体当中不仅保存了对应文件的文件描述符还保存了用户缓冲区的相关信息

  3. 操作系统有缓冲区吗?

    • 操作系统实际上也是有缓冲区的,当我们刷新用户缓冲区的数据时,并不是直接将用户缓冲区的数据刷新到磁盘或是显示器上,而是先将数据刷新到操作系统缓冲区,然后再由操作系统将数据刷新到磁盘或是显示器上。(操作系统有自己的刷新机制,我们不必关系操作系统缓冲区的刷新规则)

    • 请添加图片描述

    • 因为操作系统是进行软硬件资源管理的软件,根据下面的层状结构图,用户区的数据要刷新到具体外设必须经过操作系统

请添加图片描述


1.2 文件系统当中的inode

  • 我们知道文件可以分为磁盘文件和内存文件,内存文件前面我们已经谈过了,inode就在磁盘文件中
  • 磁盘文件由两部分构成,分别是文件内容和文件属性
  • 文件内容就是文件当中存储的数据,文件属性就是文件的一些基本信息,例如文件名、文件大小以及文件创建时间等信息都是文件属性,文件属性又被称为元信息

在命令行当中输入ls -l,即可显示当前目录下各文件的属性信息,比如下图:

请添加图片描述

在命令行当中输入ls -i,即可以查看文件的inode编号,比如下图:

请添加图片描述

为了能弄清楚inode,我们必须深入了解一下EXT2文件系统的存储方案

补充:常见的文件系统有EXT2、EXT3、XFS、NTFS等

请添加图片描述

  • Block Group:ext2文件系统会根据分区的大小划分为数个Block Group。而每个Block Group都有着相同的结构组成
  • 超级块(Super Block):存放文件系统本身的结构信息。记录的信息主要有:bolck 和 inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了
  • Group Descriptor Table(GDT):块组描述符,描述块组属性信息,有兴趣的同学可以在了解一下
  • 块位图(Block Bitmap):Block Bitmap中记录着Data Block中哪个数据块已经被占用,哪个数据块没有被占用
  • inode位图(inode Bitmap):每个bit表示一个inode是否空闲可用
  • inode Table(inode节点表):存放文件属性,如文件大小,所有者,最近修改时间等
  • Data Blocks(数据区):存放文件内容

对于磁盘与inode的深入理解:

请添加图片描述


1.3 文件属性与文件数据分开存放原理

将属性和数据分开存放的想法看起来很简单,但实际上是如何工作的呢?我们通过touch一个新文件来看看如何工作:

请添加图片描述

为了说明问题,我们将上图简化:

请添加图片描述

为了理解这个图,接下来我再引入一下:

请添加图片描述

那么我们现在就更能理解 ls 、 ls -l 、 cat 命令是再做什么了:

请添加图片描述

那么创建文件的过程我们也就可以解释了:

请添加图片描述

既然创建文件了,那么这个文件就得有它的 inode号,也就是从inode Bitmap中申请一个 inode号 ,然后从 inode Table 里的对应位置,把当前文件的 inode 属性填进去,然后如果有数据写进去了,那就在 Block Bitmap 中申请 block ,并且建立好 inode 和 block 之间的对应关系,然后将数据写进去,然后再将这个文件的文件名和 inode 号填写进当前目录的 inode Table 中

最后总结:创建一个新文件主要有一下4个操作

  1. 存储属性
    • 内核先找到一个空闲的i节点(比如这里是790231)。内核把文件信息记录到其中
  2. 存储数据
    • 该文件需要存储在三个磁盘块,内核找到空闲块:假设:300,500,800。将内核缓冲区的第一块数据 复制到300,下一块复制到500,以此类推
  3. 记录分配规则
    • 文件内容按顺序300,500,800存放。内核在inode上的磁盘分布区记录了上述块列表
  4. 添加文件名到目录
    • 比如,新的文件名 new.txt
    • linux如何在当前的目录中记录这个文件?内核将入口(790231,new.txt )添加到目录文件。文件名和inode之间的对应关系将文件名和文件的内容及属性连接起来

2.对软硬链接的理解

我们可以使用ln -s 链接文件 目标文件命令来进行软链接,首先我先来操作,让大家更容易理解软链接:

请添加图片描述

我们可以看到最后形成了软链接,而且我们可以看到 mytest 的 inode 是 790202软链接mytest-s的 inode 是 790235 ,也就是说,一个文件对应一个 inode ,也就是软链接形成的软链接文件本质是一个独立文件,也就是它有自己的 inode ,有自己独立的数据。而它数据的里面保存的是 mytest 对应的路径。这个东西特别像我们使用 windows 中的快捷方式!

因为软链接文件时独立文件,所以我们可以运行它:

使用软连接的文件也照样可以跑 mytest 这个可执行程序,说直白点,当快捷方式用

请添加图片描述

刚才我们创建的时候加 -s 创建的是软连接,如果我们不加则创建的就是硬链接:

请添加图片描述

这里我们就会发现,硬链接从 1 变为 2 了,而且原始的文件和硬链接它们的 inode 是一样的,而软连接的 inode 是独立的

请添加图片描述

请添加图片描述

所以其实硬链接的本质没有创建文件!只是建立了一个文件名和已有的 inode 的映射关系,并写入当前目录!(有点像C++中的取别名)

为了证明就是一个别名,我就先验证一下:

请添加图片描述

可以看到,虽然删除了原始的可执行,但通过硬链接的文件还是可以运行的,删除了mytest 只是将一组映射关系删除了,但是不影响另一个

当然软链接不能用了,因为存的是 mytest 的路径, mytest 都没了,有路径也没用了

我们再来看下面的操作:通过硬链接恢复删除的mytest,逆向ln使用

请添加图片描述

我们可以看到,我们通过逆向硬链接也可以将 mytest "恢复"出来

那么硬链接有什么用呢?看下面我们来研究一下

请添加图片描述

我们可以看到,如果创建一个文件(新创建的,里面没有自己新创建其它的文件),那么它的硬链接数就是 2 了,其他的文件都是 1

因为其它的文件在任何情况下,只有一组文件名和当前的 inode 有映射的关系,那dir文件呢?

请添加图片描述

首先我们知道,我们在当前目录,然后 cd . 还是当前目录,所以我们可以看到,我们进入 dir 文件,可以看到 dir 中的 . 和 dir 文件的 inode 是相同的,所以,当前这个 . 就是 dir 这个目录的别名

所以当我们用 ./mytest 的时候,实际上就是运行的 hs/mytest ,hs里的 mytest,但是当然不能这么写,这么写是运行不起来的,只是在语义上进行证明

所以之所以是 2 ,是因为 dir 自己这个文件,和 dir 文件里的 .

然后我们再来看一个现象:

请添加图片描述

我们可以看到,为什么此时 dir 的硬链接变成 3 了呢?

我们在返回上级目录的时候,是不是用cd … 这个命令,那么 … 这个命令是不是也存在于这个文件,所以:

请添加图片描述

我们看到在 newdir 里的 … 也是 790235

最后总结一下,为什么 dir 的硬连接数是 3 呢:

请添加图片描述

所以硬链接的作用就是:让我们在目录之间方面通过 . && … 跳转(通过相对路径跳转)

所以我们可以知道在 dir 这个目录下有多少子目录,因为 dir 算一个硬链接, dir 里的 . 也算一个,其他的就是子目录了

最终总结:硬链接与软链接的区别

  1. 软链接是一个独立的文件,有自己的 inode ,硬链接没有独立的 inode
  2. 硬链接的本质没有创建文件!只是建立了一个文件名和已有的 inode 的映射关系,并写入当前目录

扩展:对文件三时间的理解

我们使用stat命令可以查看对应文件的信息

请添加图片描述

这其中包含了文件的三个时间信息:

补充:文件=文件内容+文件属性

  1. Access:文件最后被访问的时间
  2. Modify:文件内容最后的修改时间
  3. Change: 文件属性最后的修改时间

关于文件三个时间的更改:

  • 当我们修改文件内容时,文件的大小一般也会随之改变,所以一般情况下Modify的改变会带动Change一起改变,但修改文件属性一般不会影响到文件内容,所以一般情况下Change的改变不会带动Modify的改变
  • 当某一文件存在时使用touch命令,此时touch命令的作用变为更新文件信息

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

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

相关文章

基于K8s构建Jenkins持续集成平台(部署流程)(转了一点)

转载至&#xff1a;https://blog.csdn.net/m0_59430185/article/details/123394853 一、传统Jenkins的Master-Slave方案的缺陷 Master节点发生单点故障时&#xff0c;整个流程都不可用了 每个 Slave节点的配置环境不一样&#xff0c;来完成不同语言的编译打包等操作&#xff0…

【Uni-App】点击分享,生成海报带二维码,保存到本地图片

目录一&#xff1a;需求二&#xff1a;分析三&#xff1a;准备工作1.qrcode准备2.并且在main.js去挂载四&#xff1a;页面构建1.html2.data3.js一&#xff1a;需求 1.产品需要这个商品&#xff0c;必须分享才有购买资格 2.一共三点&#xff0c;有海报&#xff0c;有二维码&…

k8s安装3节点集群Fate v1.8.0

集群配置信息 3节点配置信息如下图&#xff1a; 当kubefate最新版是1.9.0时&#xff0c;依赖的k8s和ingress-ngnix版本如下&#xff1a; Recommended version of dependent software: Kubernetes: v1.23.5 Ingress-nginx: v1.1.3 升级K8S到1.23.5 参考博客 https://blog.c…

HarmonyOS应用API手势方法-SwipeGesture

描述&#xff1a;用于触发滑动事件&#xff0c;滑动最小速度为100vp/s时识别成功。 Api&#xff1a;从API Version 8开始支持 接口&#xff1a;SwipeGesture(value?: { fingers?: number; direction?: SwipeDirection; speed?: number }) 参数&#xff1a; SwipeDirecti…

代码随想录刷题记录 day32无重叠区间 划分字母区间 合并区间

代码随想录刷题记录 day32无重叠区间 划分字母区间 合并区间 435. 无重叠区间 思想 其实要换个角度想&#xff0c;存放下尽可能多的区间&#xff0c;就是移除的最少的区间。可以按照左右边界进行排序。 1.如果按照右边界进行排序&#xff0c;从左往右遍历&#xff0c;选择右…

数字化门店转型| 舞蹈室管理系统| 门店小程序开发教程

很多拥有跳舞天赋的孩子从小家长就送到专业的舞蹈培训机构进行训练&#xff0c;即使成年也可以学&#xff0c;近些年来各种偶像节目繁多&#xff0c;也使得舞蹈行业市场规模增加&#xff0c;同时各个城市的舞蹈工作室也在逐年增加&#xff0c;线上各种宣传信息也比较多。 同时&…

【重磅】2022年CCF推荐期刊目录 (拟定版) 已发布~

重磅&#xff01;CCF推荐国际学术会议和期刊目录-2022(拟定版)已发布&#xff0c;一起看看有哪些新调整吧&#xff1a; MICCAI 首次被收录&#xff0c;空降B类会议&#xff1b; PRCV 首次被收录&#xff0c;空降C类会议&#xff1b; NAACL 从C类升级到B类会议&#xff1b; …

java语言【#87. 矩形的面积与周长】(已通过)

题目描述 ​ 对于一个给定长和宽的矩形&#xff0c;输出它的周长和面积。 输入 ​ 一行两个小数 a 和 b 表示矩形的长和宽。&#xff08;0.0≤a,b≤100.0&#xff09; 输出 ​ 第一行是矩形的周长 ​ 第二行是矩形的面积 ​ 结果保留两位小数 样例输入 3.1 4.1样例输出 1…

源码决定Offer薪资?这份阿里爆火“Spring源码高级手册” 成功跳槽涨薪19K

就在上周我上一家的同事兼好友去面试 Java 后端岗&#xff0c;一面过了&#xff0c;二面之后就没消息了&#xff0c;他跟我说二面问了一大堆关于Spring等框架源码底层的问题 为什么说掌握源码决定Offer薪资&#xff1f; 和大多数人一样&#xff0c;我这位好友毕业的时候很单纯…

[附源码]JAVA毕业设计火炬中学校刊在线投稿审稿系统(系统+LW)

[附源码]JAVA毕业设计火炬中学校刊在线投稿审稿系统&#xff08;系统LW&#xff09; 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;…

sonarqube个人记事本

Sonarqube安装路径 [rootshqywxtap02 sonar]# pwd /opt/sonar 查看状态 ps -ef | grep sonar bin目录中启停 ./bin/linux-x86-64/sonar.sh start ./bin/linux-x86-64/sonar.sh stop conf配置文件 添加以下参数&#xff1a; sonar.jdbc.usernamesonar sonar.jdbc.passwo…

vex-table根据时间加载列(动态加载),动态计算显示最后一行

vex-table根据时间加载列&#xff08;动态加载&#xff09;&#xff0c;动态计算显示最后一行 效果 div部分 <vxe-tableref"xTable"bordershow-footershow-overflow:loading"loading":data"partData":column-config"{ resizable: false…

【信息检索与数据挖掘期末笔记】(四)概率检索模型

为什么需要概率检索 给一个用户需求和一个文档集&#xff0c;一个检索系统需要决定文档有多满足查询 IR 系统难以理解一个查询背后的信息需求&#xff0c;并且对文档满足查询的程度做了非确定性推测 概率论可以为这种非确定性推理提供一个基本的理论 概率模型利用这个基础来估…

关于PCB布局布线,这篇文章说透了

关于PCB布局布线的问题&#xff0c;今天我们不讲信号完整性分析&#xff08;SI&#xff09;、电磁兼容性分析&#xff08;EMC&#xff09;、电源完整性分析&#xff08;PI&#xff09;。 只讲可制造性分析&#xff08;DFM) &#xff0c;可制造性设计不合理同样会导致产品设计失…

2022年12月 Faster RCNN训练自己的数据集 配置环境相对简洁

以往的大多数教程都是数年前的Faster RCNN源码&#xff0c;因为旧环境和现有环境的不同&#xff0c;导致环境配置方面出现一系列问题。特别是利用setup.py或者make.sh配置所需的环境时&#xff0c;遇到并解决一个又一个的问题&#xff0c;遗憾的是&#xff0c;失败总是贯彻全局…

嗦嗦postMessage和webSocket

前端监控 本文将从前端监控要做的3件事讲起&#xff0c;以及看看github上的web-tracing插件是怎么做的&#xff0c;尽可能展开里面关于用户体验的知识点。主要有以下几点&#xff1a; 行为监控错误收集性能监控### 行为监控 行为监控就是页面上加装摄像头&#xff0c;把我们…

基于PHP+MySQL大学宿舍管理系统的设计与实现

高等学校的住宿宿舍是住宿的第二个家,是住宿进行学习与工作的重要场地。其管理水平的高低将直接影响着住宿人才培养的质量和住宿素质教育的成效。为住宿提供一个良好的管理体系,对学校和住宿而言至关重要,因此高校公寓的建设与发展,直接影响着学校后勤社会化改革的发展进程,也直…

有趣且重要的JS知识合集(17)矩形框交互算法

之前我讲过如何用js绘制矩形框&#xff0c;下面链接快速通道~ 【JS】原生js实现矩形框的绘制/拖动/缩放 那么如何判断多个矩形框是否相交&#xff1f;嵌套还是其他的呢&#xff1f; 那下面我来分别写写关于矩形框常用的几个算法吧 1、数据格式知悉 const { startX, startY…

网页整体如何实现网页变灰效果

网页整体如何变灰?为了纪念一些影响力很大的伟人逝世或者重要的纪念日的时候需要让网页全部变灰来表示我们对逝者的悼念。 其实这个功能很简单&#xff0c;方法也有很多&#xff0c;只需要在HTML 的head标签里加入如下代码即可! <style type"text/css">html …

Vulnhub_CTF-4

目录 一 渗透测试 &#xff08;一&#xff09;信息收集 1 端口扫描 2 目录枚举 &#xff08;二&#xff09;漏洞测试 1 SQL注入 2 ssh爆破 &#xff08;三&#xff09;提权 1 sudo 提权 二 知识点 &#xff08;一&#xff09;SQL延时注入 &#xff08;二…