[Linux] Linux文件系统

news2024/11/15 17:33:25

🥁作者华丞臧.
📕​​​​专栏:【LINUX】
各位读者老爷如果觉得博主写的不错,请诸位多多支持(点赞+收藏+关注)。如果有错误的地方,欢迎在评论区指出。


文章目录

  • 一、Linux文件系统
    • 1.1 磁盘
    • 1.2 inode
    • 1.3 软硬链接
    • 1.4 动静态库


一、Linux文件系统

1.1 磁盘

信息化时代就是信息产生价值的时代,信息化是当今时代发展的大趋势,代表着先进生产力。通常我们都会将信息存放在某些硬件上,如:硬盘、内存等;当信息存放硬盘上时,信息就变成了硬盘上的文件,人们通过一些设备如电脑手机可以查看使用这些数据,我们的工作和生活,已经完全离不开视频、音乐、图片、文本、表格这样的数据文件。

  • 磁盘上存放着大量的文件,这些文件需要被管理组织起来,操作系统中管理和存储文件信息的软件机构称为文件系统。
  • 最开始存放数据的硬件是磁盘,随着时代发展,像我们的笔记本电脑大多使用SSD硬盘,但是磁盘还是主要的存储设备,可以用存放大量的数据,关键是便宜。
  • 下图是一张磁盘的结构图,磁盘的核心就是这些盘面,盘面能够记录二进制序列,其原理就是通过电流产生感应磁场来改变某些特定位置的磁极从而将电信号持久化到磁盘上。

在这里插入图片描述

  • 磁盘工作时是处于一种高速旋转的状态,磁头依靠磁盘的高速旋转引起的空气动力效应悬浮在盘面上,磁头在副轴马达的带动下可以在极短的时间内精确的切换到数据所在的磁道。

  • 磁盘是一种高精度的设备,在高速旋转的情况下,磁面上的一粒灰尘都可能会导致磁盘损坏,因此磁盘通常是在无尘的环境下密封。

  • 每一个盘面都对应一个磁臂,通过这些磁臂上的磁头来定位数据的位置,依次确定磁道(柱面)、盘面、以及扇区,这三个值称为CHS地址。
    在这里插入图片描述

  • 扇区是硬盘的最小操作单位,但扇区对于操作系统来说还是太小了,一般操作系统有自己的硬盘操作最小单位,在linux下一般为4k。
    在这里插入图片描述

  • 为了方便管理数据,我们可以将硬盘这样的物理块设备,分割成多个逻辑块设备。或者,我们也可以将多个物理块设备,组合成一个容量更大的逻辑块设备。

  • 操作系统需要管理磁盘,将磁盘抽象为一个线性的结构,类似于卷尺拉出来是线性的收进去是圆形的,因此我们可以将磁盘想象成线性的结构数组,对磁盘的管理就可以转换成对数组空间的管理了。

  • 假设磁盘抽象的出的数组为sector disk[100000000],那么我们定位一个扇区只需要数组的下标即可(这种下标称为LBA–逻辑块地址),将LBA转换成CHS地址,再将数据写入对应的磁盘上去。
    在这里插入图片描述

  • 磁盘上存储的基本单位是扇区(512字节常规),文件系统访问磁盘的基本单位是4KB,即一次IO访问8个扇区。

  • 这样做有两个好处:一、提高IO的效率二、让软件(OS)和硬件(磁盘)具有强相关性即解耦合

1.2 inode

使用ll查看文件,除了文件名还可以看到文件的其他属性,如下图:
在这里插入图片描述
每行包含7列:

  • 模式:代表文件的类型以及权限
  • 硬链接数
  • 文件所有者
  • 所属组
  • 文件大小
  • 最后修改时间
  • 文件名

如果需要查看文件更详细的信息可以使用stat命令,如下图:
在这里插入图片描述
在上图中我们可以看到文件属性中有一个Inode字段,在Linux系统中inode用于表示唯一的一个文件。

  • 不管是在Windows平台还是在Linux系统中,我们都可以通过绝对路径或相对路径找到一个唯一的文件,前提是在同一目录下都不允许重名的文件出现。
  • 文件是存放在磁盘上的,不管是普通文本文件还是文件夹(Linux上通常称为目录)都属于文件的一种,目录也是文件;在这种情况下,操作系统如何在磁盘上查找到目标文件的呢 —— 给定一个一对一的映射关系。

Linux ext2文件系统,下图为磁盘一个分区的文件系统图(内核内存映像肯定有所不同),磁盘是典型的块设备,硬盘分区被划分为一个个的block。一个block的大小是由格式化的时候确定的,并且不可以更改。例如mke2fs的-b选项可以设定block大小为1024、2048或4096字节。而下图中启动块(Boot Block)的大小是确定的。

在这里插入图片描述

  • 启动块(Boot Block):里面包含操作系统的位置以及分区表,开机信息。
  • Block Group :ext2文件系统会根据分区的大小划分为数个Block Group。而每个Block Group都有着相同的结构组成。
  • 超级块(Super Block):存放文件系统本身的结构信息。记录的信息主要有:bolck 和 inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了,因此超级快通常会备份一定数量。
  • GDT(Group Descriptor Table) :块组描述符,描述块组属性信息,记录inode数、起始inode编号、block使用量以及剩余量等等信息。
  • 块位图(Block Bitmap):Block Bitmap中记录着Data Block中哪个数据块已经被占用,哪个数据块没有被占用。
  • inode位图(inode Bitmap):每个bit表示一个inode是否空闲可用。
  • i节点表(inode table):以128字节为单位,存放文件属性 如 文件大小,所有者,最近修改时间等。
  • 数据区(Data Blocks):以4KB为单位,存放文件内容。

在inode table中保存了文件对应的所有属性,那么一个inode如何与属于自己的文件内容关联起来呢?

struct inode
{
	// 文件所有属性
	...
	blocks[15];
	...
}
//在inode的结构体中包含一个blocks的数组,这个数组保存了文件对应的block编号
//其中[0, 11]:直接保存该文件的blocks编号
//[12, 15]:指向一个datablock但是这个datablock不保存有效数据,而保存该文件所对应的其它块编号

还要注意的是,文件名也是文件属性,但是inode里面并不保存文件名;Linux下,底层实际都是通过inode编号来标识文件。那么操作系统是如何准确帮用户通过文件名找到对应的文件内容呢?首先,用户对文件进行操作时都是在一个目录下,不管是创建还是删除。其次目录也是一个文件,既然是文件就有属性和内容,其属性与普通文件类似,那么目录文件的内容是什么呢?

文件名并沒有被保存在文件内容中,操作系统又必须通过文件名帮用户查找文件内容,所以文件inode和文件名必须具有映射关系并且记录下来,在Linux系统中文件名和文件inode的映射关系被保存在目录的内容中。同时我们也注意到,Linux同一个目录下,不可以创建多个同名文件,这说明文件名本身是一个具有Key值的东西。

  • 创建一个新文件:当我们创建好一个新文件时,操作系统会找到自己所处的目录下,根据目录的inode编号查找到目录的datablock,然后将文件名和inode映射关系写入目录的数据块中。
  • 删除文件:操作系统删除一个文件并不会直接清除数据,而是将标记该文件对应的属性和数据块的相关位图清除(由1置0),所以删除的文件是可以恢复的。

1.3 软硬链接

  • 硬链接:通过索引节点(inode)来链接。
  • 软链接:通过名字引用另外一个文件。
  • 通过ls -l可以查看文件的硬链接数:
    在这里插入图片描述
//创建一个软链接
ln -s 目标文件名 软链接名

//查看文件inode编号
ls -i

在这里插入图片描述

上图可以看到软链接和目标文件使用的inode编号是不同的,软链接具有独立的inode编号;并且通过软链接mytest文件可以直接运行目标文件test,软链接相当于一个快捷方式,类似Windows系统,其中所保存的内容是指向文件所在路径。

//创建一个硬链接
ln 目标文件 硬链接名

在这里插入图片描述
硬链接不是独立的文件,相当于一个指针,指向某一个inode,而硬链接数就是引用计数,有几个硬链接指向该inode编号硬链接数就是几。

Linux中我们常见目录如下
.  :当前目录
.. :上一级目录

这两个目录就是硬链接

在这里插入图片描述

软硬链接的区别:软链接是一个独立的文件,有自己独立的inode编号;硬链接不是一个独立的文件,它和目标文件使用的是同一个inode。

1.4 动静态库

  • 静态库:程序在编译链接的时候把库的代码链接到可执行文件中,程序运行的时候将不再需要静态库;静态库Linux下后缀为.a文件,windows下后缀为.lib文件。
  • 动态库:程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。动态库Linux下后缀为.so文件,windows下后缀为.dll文件。在Linux下,程序生成默认是动态连接。
  • 动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间
测试程序
 /add.h/
 #ifndef __ADD_H__
 #define __ADD_H__ 
 
 int add(int a, int b); 
 #endif // __ADD_H__
 /add.c/
 #include "add.h"
 
 int add(int a, int b)
 {
 	return a + b;
 }
 /sub.h/
 #ifndef __SUB_H__
 #define __SUB_H__ 
 
 int sub(int a, int b); 
 #endif // __SUB_H__
 /add.c/
 #include "add.h"
 
 int sub(int a, int b)
 {
 	return a - b;
 }
 ///main.c
 #include <stdio.h>
 #include "add.h"
 #include "sub.h"
 
 int main( void )
 {
 	int a = 10;
 	int b = 20;
 	printf("add(10, 20)=%d\n", a, b, add(a, b));
 	a = 100;
 	b = 20;
 	printf("sub(%d,%d)=%d\n", a, b, sub(a, b));
 }

//生成静态库
ar -rc libmymath.a add.o sub.o 
ar是gnu归档工具,rc表示(replace and create)

//查看静态库中的目录列表
ar -tv libmymath.a   
t:列出静态库中的文件

//gcc编译链接第三方库
gcc main.c -L. -lmymath
-L 指定库路径
-l 指定库名

在这里插入图片描述

将生成的静态库删除后,程序依旧可以正常运行,如下图:
在这里插入图片描述

//生成动态库
//shared: 表示生成共享库格式
//fPIC:产生位置无关码(position independent code)
//库名规则:libxxx.so
gcc -fPIC -c sub.c add.c
gcc -shared -o libmymath.so add.o sub.o

在这里插入图片描述
同样是上面的add.c和sub.c文件形成.o文件再生成一个动态库,将动态库使用gcc编译main.c文件形成可执行文件,在删除动态库之后,此时与静态库不同,该文件运行出错表示该动态库不存在。
那么链接静态库的时候为什么没有这个问题呢?或者说链接动态库和静态库两者的区别是什么呢?

  • 静态链接,是将所需要的库文件中的代码拷贝进我们自己的代码中,然后再形成一个可执行程序,运行时程序中已经包含了库中的代码不需要依赖库。
  • 与静态链接不同,一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码;在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接。

我们使用的库都是存放在磁盘上的文件,动态链接的可执行程序运行时会将动态链接库加载到内存中,加载到内存中的库代码只有一份,进程通过页表将进程地址空间和库链接起来,当使用动态链接库中的函数时会跳转到库中运行。
在这里插入图片描述

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

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

相关文章

Philosophy of life: growing flowers in your heart

Growing flowers in your heart An aged man lived in a nice cottage with a large garden in a town in England. He is seen busy looking after his flowers all time. 第一部分介绍的是: 有一个老人在英格兰的镇上有一个带大花园的屋子&#xff0c;他一直在忙着照顾他的花…

机器学习实战:带你进入AI世界!

机器学习是人工智能领域的一个重要分支&#xff0c;可以帮助我们从大量数据中发现规律&#xff0c;进行预测和分类等任务。然而&#xff0c;想要真正掌握机器学习算法&#xff0c;并将其应用到实际问题中&#xff0c;还需要进行大量的实战练习。 本文将介绍几个常见的机器学习实…

seurat -- 细胞注释部分

文章目录 brief寻找差异基因部分注释细胞部分详细参数 brief 细胞注释大概分为两步&#xff1a;差异基因 --> marker genes —> map reference 差异基因可以是表达量上存在差异也可以是表达细胞占比上存在差异&#xff0c;通常二者兼顾考虑。 marker genes 个人理解为…

蓝牙网状网络的基本原理及应用开发

借助蓝牙 5 的网状网络功能&#xff0c;开发人员可以增强无线连接系统&#xff08;如物联网设备&#xff09;的通信范围和网络可用性。但是&#xff0c;网状网络的低功耗无线硬件设计与网状网络软件开发之间存在着复杂的层次&#xff0c;这可能会使开发人员迅速陷入混乱并危及项…

GLM论文精读-自回归填空的通用语言模型

GLM作为ChatGLM的前期基础论文&#xff0c;值得精读。本文是对GLM论文的精读笔记&#xff0c;希望对大家有帮助。GLM主要思想概述&#xff0c;利用自回归填空的思想&#xff0c;基于transformer的编码器实现了同时在NLU和有无条件生成任务上较好的表现。 基本信息 原文&#…

设计模式 -- 备忘录模式

前言 月是一轮明镜,晶莹剔透,代表着一张白纸(啥也不懂) 央是一片海洋,海乃百川,代表着一块海绵(吸纳万物) 泽是一柄利剑,千锤百炼,代表着千百锤炼(输入输出) 月央泽,学习的一种过程,从白纸->吸收各种知识->不断输入输出变成自己的内容 希望大家一起坚持这个过程,也同…

邮件营销自动化:优化营销流程,提升转化率

对于希望与客户联系&#xff0c;并推广其产品或服务的企业来说&#xff0c;电子邮件营销是一个强大的工具。然而&#xff0c;随着电子邮件通信量的持续增长&#xff0c;企业要跟上客户对个性化和及时性消息的需求&#xff0c;可能会面临一定的挑战。而这就是电子邮件营销自动化…

干货满满!破解FP安全收款难题

怎样安全收款是做擦边产品卖家比较忧虑的问题&#xff0c;2023年已经即将来到了年中&#xff0c;跨境卖家们在这一方面做得怎么样了呢&#xff1f; 这期分享破解FP独立站收款难题的方法。 一、商家破解FP收款难题方法 1.第三方信用通道 优点&#xff1a;信用卡在国外使用率比…

强化学习p2-价值学习

基本概念 折扣回报(Discounted Return) 在 MDP 中&#xff0c;通常使用折扣回报 (discounted return)&#xff0c;给未来的奖励做折扣。折扣回报的定义如下: U t R t γ R t 1 γ 2 R t 2 γ 3 R t 3 . . . U_t R_t\gamma R_{t1}\gamma ^2R_{t2}\gamma ^3R_{t3}...…

【IoT】<硬件产品经理进阶课> 正式在CSDN学院上线

目录 课程目录 适用人群 课程介绍 课程地址 课程目录 001-产品经理进阶&#xff1a;开课介绍 002-产品经理进阶&#xff1a;产品经理简介 003-产品经理进阶&#xff1a;产品经理所需具备的核心素质 004-产品经理进阶&#xff1a;产品经理的进阶路径 005-产品经理进阶&a…

指定城市|眼科医生入世界名校斯坦福大学访学深造

J医生计划利用一年时间自费到美国进行访学交流。提出的要求是专业匹配&#xff0c;兼顾基础医学研究及眼科临床观摩&#xff0c;并且指定城市&#xff0c;希望在今年3、4月份出国。最终我们确定了世界名校斯坦福大学。邀请函上明示&#xff1a;访学期间除从事基础研究外&#x…

手把手教你学习PyQT5:打造精美、功能强大的桌面应用程序(更新中。。)

目录 前言一、PyQt5介绍&开发环境安装&简单案例分析1-1、PyQt5的介绍1-2、开发环境安装1-3、简单案例分析 二、QT Designer2-1、安装和配置2-2、QT Designer基础入门2-3、ui文件转换为python文件 三、PyQt5基本窗口控件&#xff08;QMain Window、Qwidget、QDialog、Ql…

C# 利用ffmpeg的image2pipe参数实现USB摄系头本地预览同时推流

本地USB摄像头在使用中时&#xff0c;不支持另一个程序的并发访问&#xff0c;也就是所USB摄像头只能令第一个连接的程序“独享”。 在开发一个软件时&#xff0c;希望实现预览USB摄像头的同时&#xff0c;实现摄像头的推流。 推流要用的ffmpeg&#xff0c;经过资料查找&…

mac m2芯片 安装 brew 和cocoapods

Homebrew的安装 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 这里可能会失败&#xff0c;如 git clone 时候报错 error: RPC failed; curl 92 HTTP/2 stream 5 was not closed cleanly before end of the underlyi…

进程(二)

进程二 2.6 调度的概念、层次2.6.1 基本概念2.6.2 三个层次2.6.3 三层调度的联系、对比2.6.4 补充知识2.6.5 本小节总结 2.7 进程调度的时机、切换与过程、方式2.7.1 进程调度的时机2.7.2 切换与过程2.7.3 进程调度的方式2.7.4 总结 2.8 调度器/调度程序/闲逛线程2.9 调度算法的…

HTML5 + JavaScript绘柱状图

之前用HTML5 JavaScript绘柱状图&#xff0c;可以直观显示各类型产品或品牌的所占比例大小。详见&#xff1a; HTML5 JavaScript绘柱状图1 现在需要针对每年获得各类品牌数据进行对比&#xff0c;绘制柱状图会更直观。 首先我们定义二维数组aBrandType&#xff0c;存放品牌…

双指针的基本应用

一、环形链表 I 方法1:哈希表 struct hashTable {struct ListNode* key;UT_hash_handle hh; };struct hashTable* hashtable;struct hashTable* find(struct ListNode* ikey) {struct hashTable* tmp;HASH_FIND_PTR(hashtable, &ikey, tmp);return tmp; }void insert(struc…

页面一打开就有30个重复请求,优化方法

一、写在前面 上周测试同事给我提了个bug。他说在公司运营系统某个编辑页面中&#xff0c;一个post请求调用太多次了&#xff0c;想让我看看怎么回事。我刚听他讲这个事情时心里有点不屑一顾&#xff0c;觉得能有多少次啊&#xff0c;大惊小怪的。然而当我在测试环境中打开那个…

经典文献阅读之--A Lifelong Learning Approach to Mobile Robot Navigation(终生学习轨迹导航)

0. 简介 终生学习作为近年来比较火的一种深度学习方式&#xff0c;导航终身学习(LLfN)旨在解决标准导航问题的一种新变体&#xff0c;在该问题中&#xff0c;智能体在有限的内存预算下&#xff0c;通过学习提高在线经验或跨环境的导航性能。而最近有一篇文章《A Lifelong Lear…

Python数据分析实战【十四】:你知道python中有几种排序方法吗【文末源码地址】

文章目录 一、List.sort()排序案例一&#xff1a;按照列表中的元素进行排序案例二&#xff1a;按照销售额数据进行排列 二、sorted()排序案例一&#xff1a;sorted()对列表进行排序案例二&#xff1a;sorted()对字典进行排序案例三&#xff1a;sorted()对列表中的字典元素排序 …