Linux -- 文件【下】

目录

一、EXT2文件系统

1、宏观认识

2、块组内部构成

2.1 Data Block

2.2 i节点表(Inode Table)

2.3 块位图(Block Bitmap)

2.4 inode位图(Inode Bitmap) 

2.5 GDT(Group Descriptor Table) 

2.6 超级块(Super Block)

3、目录与文件名

4、路径解析

5、路径缓存

6、挂载分区 

7、文件名与inode映射实验

8、inode和datablock映射

9、 问题总结

二、软硬链接 

1、软连接

2、硬链接

三、文件时间-ACM

四、文件系统总结 


一、EXT2文件系统

1、宏观认识

# 所有的准备⼯作都已经做完,是时候认识下⽂件系统了。我们想要在硬盘上储⽂件,必须先把硬盘格式化为某种格式的⽂件系统,才能存储⽂件。⽂件系统的⽬的就是组织和管理硬盘中的⽂件。

# 在Linux 系统中,最常⻅的是 ext2 系列的⽂件系统。其早期版本为 ext2,后来⼜发展出 ext3ext4ext3 ext4 虽然对 ext2 进⾏了增强,但是其核⼼设计并没有发⽣变化,我们仍是以较⽼的 ext2 作为演示对象。

ext2⽂件系统将整个分区划分成若⼲个同样⼤⼩的块组 (Block Group),如下图所⽰。只要能管理⼀个分区就能管理所有分区,也就能管理所有磁盘⽂件。

# 上图中启动块(Boot Block/Sector)的⼤⼩是确定的,为1KB,由PC标准规定,⽤来存储磁盘分区信息和启动信息,任何⽂件系统都不能修改启动块。启动块之后才是ext2⽂件系统的开始。

 # ext2⽂件系统会根据分区的⼤⼩划分为数个Block Group。⽽每个Block Group都有着相同的结构组成。

2、块组内部构成

2.1 Data Block

# 数据区:存放⽂件内容,也就是⼀个⼀个的Block。根据不同的⽂件类型有以下⼏种情况:

  • 对于普通⽂件,⽂件的数据存储在数据块中。
  • 对于⽬录,该⽬录下的所有⽂件名和⽬录名存储在所在⽬录的数据块中,除了⽂件名外,ls -l命令看到的其它信息保存在该⽂件的inode中。
  • Block 号按照分区划分,不可跨分区

2.2 i节点表(Inode Table)

  • 存放文件属性如文件大小,所有者,最近修改时间等
  • 当前分组所有inode属性的集合
  • inode编号以分区为单位,整体划分,不可跨分区

2.3 块位图(Block Bitmap)

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

2.4 inode位图(Inode Bitmap) 

  • 每个bit表示一个inode是否空闲可用。

2.5 GDT(Group Descriptor Table) 

# 块组描述符表,描述块组属性信息,整个分区分成多少个块组就对应有多少个块组描述符。每个块组描述符存储一个块组的描述信息,如在这个块组中从哪里开始是inode Table,从哪里开始是Data Blocks,空间的inode和数据块还有多少个等等。块组描述符在每个块组的开头都有一份拷贝。

  • 块组内的inode表的块位置
  • 块组内的块位图和inode位图的块位置
  • 块组内已使用和空闲的块数对inode
  • 块组的块分配策略信息
// 磁盘级blockgroup的数据结构
struct ext2_group_desc
{__le32 bg_block_bitmap;  /* Blocks bitmap block */__le32 bg_inode_bitmap;  /* Inodes bitmap block */__le16 bg_inode_table;   /* Inodes table block */__le16 bg_free_blocks_count;/* Free blocks count */__le16 bg_free_inodes_count;/* Free inodes count */__le16 bg_used_dirs_count;/* Directories count */__le16 bg_pad;__le16 bg_reserved[3];
};

2.6 超级块(Super Block)

# 存放⽂件系统本⾝的结构信息,描述整个分区的⽂件系统信息。记录的信息主要有:bolckinode的总量,未使⽤的blockinode的数量,⼀个blockinode的⼤⼩,最近⼀次挂载的时间,最近⼀次写⼊数据的时间,最近⼀次检验磁盘的时间等其他⽂件系统的相关信息。Super Block的信息被破坏,可以说整个⽂件系统结构就被破坏了。

  • 文件系统的大小(总块数)
  • 每个块的大小
  • inode的大小和数量
  • 块组的数量

# 超级块在每个块组的开头都有⼀份拷⻉(第⼀个块组必须有,后⾯的块组可以没有)。 为了保证⽂件系统在磁盘部分扇区出现物理问题的情况下还能正常⼯作,就必须保证⽂件系统的super block信息在这种情况下也能正常访问。所以⼀个⽂件系统的super block会在多个block group中进⾏备份,这些super block区域的数据保持⼀致。

3、目录与文件名

 # 问题:那目录呢?目录如何存储的呢?

# 目录也是按照前面我们说的方式存储的,也就是说目录也有自己的inode,无非就是在inode结构体里面使用type标记位来区分,不管是目录还是文件,其他都和文件一样。

# 那目录的内容存储什么啊?即目录文件的数据块存储什么呢?答案是文件名->inode映射关系

# 所以在磁盘中保存文件就没有目录的概念,都是inode和数据,具体是文件还是目录,可以通过inode区分。因为磁盘只认inode,所以我们今天打开一个code.cc一定是先找到文件所处的目录然后根据code.cc,查找目录映射关系的inode,再根据inode确定分区和分组,加载inode属性内容。此时我们Is就看到文件属性!

# 所以,访问⽂件,必须打开当前⽬录,根据⽂件名,获得对应的inode号,然后进⾏⽂件访问。访问⽂件必须要知道当前⼯作⽬录,本质是必须能打开当前⼯作⽬录⽂件,查看⽬录⽂件的内容!

4、路径解析

5、路径缓存

 

6、挂载分区 

# 问题:我们有一个分区->格式化->能否使用这个分区了?答案是不能。我们可以通过Is /dev/vda* -l查看云服务器的磁盘,可以看到我们云服务器有3个/dev/vad分区,并且我们无法直接进入这个分区。为什么?因为我们的分区需要和一个特定目录进行关联,之后进入这个目录就相当于进入这个分区。这也叫做把目录和分区进行挂载! 接下来我们做一个试验来理解:

# 这里我们命令相当于从/dev/zero这个文件里面读取内容,然后把内容设置为0,写入到指定文件disk.img里面,写入块大小为1M。分区就是一个磁盘空间,形成一个文件就相当于形成一个磁盘空间!所以这里我们就有一个disk.img的5M的文件! 

# 然后我们使用mkfs.ext4 命令格式化分区内容为ext4文件系统,写入文件系统本质就是清空两个位图,然后给分区分组。可以看到我们分配了1280个inode、1280个blocks。此时他已经被我们格式化为一块盘了。

# 然后此时我们使用 df-h 命令查看挂载情况,同时还有文件系统的使用率、分区大小等。发现我们的/dev/vda3 和根目录挂载了,所以我只要登录操作系统就会处在/dev/vda3分区。

# 然后我们可以使用 mount 命令,把分区挂载到 /mnt/mydisk 目录里面。此时我们 df-h 查看,发现确实已经挂载上了。 

 # 所以此时我们在/mnt/mydisk 创建文件,就是在disk.img所在的分区里面创建文件了。

# 我们要取消挂载,就可以使用 umont 命令,然后再 rm disk.img 即可。

  

# 我们已经能够根据inode号在指定分区找⽂件了,也已经能根据⽬录⽂件内容,找指定的inode了,在指定的分区内,我们可以为所欲为了。可是:

# 问题:inode不是不能跨分区吗?Linux不是可以有多个分区吗?我怎么知道我在哪⼀个分区???

# 所以结论就是:

7、文件名与inode映射实验

# 我们说目录在磁盘上的数据块保存的是文件名和inode的映射关系,现在我们写了一份代码,先调用opendir 打开一个文件目录,然后调用 readdir 就可以使用一个文件的描述符,然后返回一个结构体,这个结构体包含目录中文件的属性相关信息,然后把里面包含的文件名和inode映射关系打印出来 。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/types.h>
#include <unistd.h>int main(int argc, char *argv[]) 
{if (argc != 2) {fprintf(stderr, "Usage: %s <directory>\n", argv[0]);exit(EXIT_FAILURE);}DIR *dir = opendir(argv[1]); // 系统调⽤,⾃⾏查阅if (!dir) {perror("opendir");exit(EXIT_FAILURE);}struct dirent *entry;while ((entry = readdir(dir)) != NULL) { // 系统调⽤,⾃⾏查阅// Skip the "." and ".." directory entriesif (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {continue;}printf("Filename: %s, Inode: %lu\n", entry->d_name, (unsigned long)entry->d_ino);}closedir(dir);return 0;
}

# 我们发现确实和我们 Is -li 查看到的文件名和inode是一样的!说明我们的目录内容就是保存文件名和inode的映射关系! 

8、inode和datablock映射

# inode内部存在 __le32 i_block[EXT2_N_BLOCKS]; /* Pointers to blocks */,EXT2_N_BLOCKS =15,就是用来进行inodeblock映射的。这样文件=内容+属性,就都能找到了。

# 我们在ext2_inode上可以发现存在一个i_blocks数组,这个数组的大小是15,这个就是我们说的inode和数据块的映射数组!

# 如果我们的数组只填写数据块编号的15*4kb=60kb,而平时我们的随便一个文件都是M为单位的,60kb根本不够看啊! 所以这个数组只有前12个位置存储数据块编号映射关系,后面三个存储一级、二级、三级块索引指针 。

# 一级索引指针指向一个4kb的block,这4kb的block不是直接存储文件数据,而是存储文件数据块的地址。假设指针大小为4字节,就有了4kb/4字节=1024个数据块索引。二级索引指向的就是一级索引,以此类推所以我们就可以扩展我们保存的数据块索引!

9、 问题总结

# 通过上面的学习,我们就可以回答一下几个问题: 

1. 如何理解创建一个空文件?

  1. 遍历inode Bitmap,找到比特位为0的位置,申请一个未被使用的inode
  2. inode表中找到对应的inode, 并将文件的属性信息填到inode结构当中。
  3. 将该文件的文件名和inode指针添加到目录文件的数据块当中。

2. 如何理解向文件写入信息?

  1. 通过文件的inode编号找到对应的inode结构。
  2. 通过inode结构找到存储该文件内容的数据块,并将数据写入数据块。
  3. 若不存在数据块或者申请的数据块已经写满了,就需要遍历block Bitmap找到一个空的块号,并在数据区当中找到对应的空闲块,再把数据写入到数据块当中,最后还需要建立数据块和inode结构的对应关系。

3. 删除文件做了些什么?

  1. 将该文件对应的inodeInode map当中设置为无效。
  2. 将该文件申请过的Data BlockBlock map当中置为无效。

# 这也是我们为什么删除一个软件的速度比下载同一个软件的速度快的多的原因。当然因为文件内容并没有被删除,所以我们可以在对应内容被其他文件内容覆盖之前,通过一些技术手段复原已删除文件。 

4. 如何理解目录?

目录也是一种文件,是文件就有对应的文件属性与文件内容,其中对应的文件属性就是我们的inode存储的就是目录的大小,目录的拥有者等。而对应的文件内容存储的就是该目录下的文件名以及对应文件的inode指针。


二、软硬链接 

1、软连接

# 软链接又叫做符号链接,软链接文件是一个独立的文件,该文件有自己的inode号,但是该文件只包含了源文件的路径名,所以软链接文件一般就是对应路径文件的一种快捷访问方式。其中在Windows系统中,我们桌面上软件图标就是访问对应程序的快捷方式,本质其实就是一个软连接文件。

# 在Linux中,我们可以通过指令ln -s 文件名 软链接名设置软连接:

# 我们向code.c追加重定向,发现通过软连接也可以查看code.c的内容,所以软连接其实就是类似我们的快捷方式!

# 通过快捷方式就可以找到我们的可执行程序,而我们的快捷方式是一个独立的文件,所以我们删除快捷方式并没有真正删除软件,所以我们软连接也是一个独立的文件,所以我们可以看到code.ccode-softinode不同!

# 并且我们也能通过指令unlink 软连接名取消对应的软连接,并且如果一旦删除软连接所指向的文件,那么该软连接文件也将毫无意义。 

2、硬链接

硬链接文件就是源文件的一个别名,它与源文件之间具有相同的inode大小。一旦为某个文件建立硬链接,那么对应的硬链接数就会加1。

# 在Linux中,我们可以通过指令ln 文件名 硬链接名建立对应的硬链接,同样我们也能通过unlink 硬链接名取消对应的硬链接。

# 硬链接没有独立的inode,并不是一个独立的文件, 本质是在特定的目录下,添加一个文件名和inode编号的映射关系。 

  


三、文件时间-ACM

# 在Linux中,我们可以使用指令stat 文件名来查看对应文件的信息。

# 以下是对应关于文件时间的信息:

  • Access: 文件最后被访问的时间。
  • Modify: 文件内容最后的修改时间。
  • Change: 文件属性最后的修改时间。 

# 当我们修改文件内容时,文件的大小一般也会随之改变,所以一般情况下Modify的改变会影响Change一起改变,但修改文件属性一般不会影响到文件内容,所以一般情况下Change的改变不会影响Modify的改变。

# 我们若是想将文件的这三个时间都更新到最新状态,可以使用指令touch 文件名


四、文件系统总结 

# 下⾯⽤⼏张图总结,主要想从不同⻆度说明:

 

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

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

相关文章

谷歌手机刷机和面具ROOT保姆级别教程

#比较常用的谷歌输入root面具教程,逆向工程师必修课程# 所需工具与材料清单 真机设备 推荐使用 Google Pixel 4 或其他兼容设备&#xff0c;确保硬件支持刷机操作。 ADB 环境配置 通过安装 Android Studio 自动配置 ADB 和 Fastboot 工具。安装完成后&#xff0c;需在系统环境…

平衡二叉搜索树 - 红黑树详解

文章目录一、红黑树概念引申问题二、红黑树操作一、红黑树概念 红黑树是一棵二叉搜索树&#xff0c;它在每个节点上增加了一个存储位用来表示节点颜色(红色或者黑色)&#xff0c;红黑树通过约束颜色&#xff0c;可以保证最长路径不超过最短路径的两倍&#xff0c;因而近似平衡…

从0开始跟小甲鱼C语言视频使用linux一步步学习C语言(持续更新)8.14

第十六天 第五十二&#xff0c;五十三&#xff0c;五十四&#xff0c;五十五和五十六集 第五十二集 文件包含 一个include命令只能指定一个被包含文件 文件允许嵌套&#xff0c;就是一个被包含的文件可以包含另一个文件。 文件名可以用尖括号或者双引号括起来 但是两种的查找方…

B+树索引分析:单表最大存储记录数

在现代数据库设计中&#xff0c;随着数据量的增加&#xff0c;如何有效地管理和优化数据库成为了一个关键问题。根据阿里巴巴开发手册的标准&#xff0c;当一张表预计在三年内的数据量超过500万条或者2GB时&#xff0c;就应该考虑实施分库分表策略 Mysql B树索引介绍 及 页内储…

三、memblock 内存分配器

两个问题&#xff1a; 1、系统是怎么知道物理内存的&#xff1f;linux内存管理学习&#xff08;1&#xff09;&#xff1a;物理内存探测 2、在内存管理真正初始化之前&#xff0c;内核的代码执行需要分配内存该怎么处理&#xff1f; 在Linux内核启动初期&#xff0c;完整的内存…

Python 桌面应用形态后台管理系统的技术选型与方案报告

下面是一份面向“Python 桌面应用形态的后台管理系统”的技术选型与方案报告。我把假设前提→总体架构→客户端技术选型→服务端与数据层→基础设施与安全→交付与运维→质量保障→里程碑计划→风险与对策→最小可行栈逐层给出。 一、前置假设 & 非功能目标 业务假设 典型…

Winsows系统去除右键文件显示的快捷列表

前言&#xff1a;今天重做了电脑系统&#xff0c;安装的是纯净版的系统。然后手动指定D盘安装了下列软件。&#xff08;QQ&#xff0c;迅雷&#xff0c;百度网盘&#xff0c;搜狗输入法&#xff0c;驱动精灵&#xff09;然后我右键点击桌面的软件快捷方式&#xff0c;出现了一排…

【Go】Gin 超时中间件的坑:fatal error: concurrent map writes

Gin 社区超时中间件的坑&#xff1a;导致线上 Pod 异常重启 在最近的项目中&#xff0c;我们遇到了因为 Gin 超时中间件&#xff08;timeout&#xff09; 引发的生产事故&#xff1a;Pod 异常退出并重启。 问题现场 pod无故重启&#xff0c;抓取标准输出日志&#xff0c;问题…

数据结构:用数组实现队列(Implementing Queue Using Array)

目录 第1步&#xff1a;设计蓝图 (The Struct) 第2步&#xff1a;队列的诞生 (创建与初始化) 第3步&#xff1a;状态检查 (判满与判空) 第4步&#xff1a;核心操作 (入队与出队) 入队 (Enqueue) 出队 (Dequeue) 第5步&#xff1a;善后工作 (销毁队列) 现在&#xff0c;我…

Boost库核心组件与应用

一、BOOST 库简介&#xff1a;C 开发者的 “扩展工具集” 在 C 编程领域&#xff0c;除了标准库&#xff08;STL&#xff09;外&#xff0c;BOOST 库是最具影响力的第三方库之一。它由全球数百位开发者共同维护&#xff0c;包含超过 160 个高质量的组件&#xff0c;覆盖从基础…

机器学习 [白板推导](十二)[卡曼滤波、粒子滤波]

15. 线性动态系统&#xff08;卡曼滤波&#xff0c;Kalman Filter&#xff09; 15.1. 概述 15.1.1. 背景介绍 变量随时间变化的系统叫做动态系统&#xff0c;其中隐变量取值离散的是隐马尔可夫模型&#xff08;HMM&#xff09;&#xff0c;而隐变量取值连续的分为线性动态系统…

RH134 访问网络附加存储知识点

1. NFS 的主要功能是什么&#xff1f;答&#xff1a;NFS是一种分布式文件系统协议&#xff0c;主要功能包括&#xff1a;允许远程计算机通过网络访问共享文件。 实现文件系统在客户端和服务器之间的透明访问。支持文件的共享、读取和写入&#xff0c;使得多个 …

组合模式及优化

组合模式是一种结构型设计模式&#xff0c;其核心思想是将对象组合成树形结构&#xff0c;以表示“部分-整体”的层次关系&#xff0c;使得用户对单个对象和组合对象的使用具有一致性。 一、介绍 核心角色 组合模式包含以下3个关键角色&#xff1a; 抽象组件&#xff08;Compon…

【wmi异常】关于taskkill命令提示“错误:找不到” 以及无法正常获取设备机器码的处理办法

记录一下我的解决方案。 我先查阅了这篇博客&#xff1a;https://blog.csdn.net/qq_45698181/article/details/138957277 发现他写的批处理不知怎么执行不了&#xff0c;后来问了ai又可以执行了&#xff0c;估计是csdn防盗版格式问题 这里写一下我跟ai的对话&#xff0c;大家可…

制造装配、仓储搬运、快递装卸皆适配!MinkTec 弯曲形变传感器助力,让人体工学改变劳动生活

【导语】Minktec 最新实验显示&#xff1a;将Minktec 柔性弯曲形变传感器FlexTail 贴于受试者背部&#xff0c;记录 1 分钟内从洗碗机取餐具的动作&#xff0c;结合配套的flexlib -专用Python库分析&#xff0c;不仅量化出 “越低越伤腰” 的结论&#xff0c;更为制造装配、物流…

Nginx蜘蛛请求智能分流:精准识别爬虫并转发SEO渲染服务

> 一招解决搜索引擎爬虫无法解析现代前端框架的痛点,提升网站收录率与SEO排名! **痛点场景**:你的网站采用Vue/React等前端框架构建,页面内容依赖JavaScript动态渲染。搜索引擎爬虫访问时,只能抓取到空HTML骨架,无法获取真实内容,导致网站收录率低、SEO效果差。 --…

链表。。。

目录 5.1 链表的结点 5.2 插入 5.3 链表长度 5.4 查找 5.5 指定位置删除 5.6 代码 5.1 链表的结点 一个结点包括&#xff1a;值和指向下一个结点的指针。 package com.qcby.链表;public class Node {int value;Node next;public Node(int val){valueval;}Overridepublic…

私人AI搜索新突破:3步本地部署Dify+Ollama+QwQ,搜索能力MAX

1.安装Docker容器 本地部署Dify要先安装Docker桌面版&#xff0c;跟Ollama一样简单&#xff0c;也是去官网下载对应版本文件&#xff0c;直接安装就OK。 2&#xff1a;安装Dify 安装 Dify 简单的方式就是git clone&#xff0c;复制其github地址github.com/langgenius/dify&am…

(2-10-1)MyBatis的基础与基本使用

目录 0.前置小节 1. MyBatis 框架介绍 1.1 软件开发中的框架 1.2 使用框架的好处 1.3 SSM 开发框架 1.4 什么是 MyBatis 1.5 MyBatis 的开发流程 2. MyBatis 的开发流程 2.0 MyBatis的工作流程 2.1 引入 MyBatis 依赖 00.base(目录、pom、单元测试、Junit4) 01.Cal…

StarRocks集群部署

Starrocks 是一款基于 MPP 架构的高性能实时分析型数据库&#xff0c;专为 OLAP&#xff08;联机分析处理&#xff09;场景 设计&#xff0c;尤其擅长处理海量数据的实时分析、复杂查询和多维统计。 硬件 CPU&#xff1a;StarRocks依靠AVX2指令集充分发挥其矢量化能力。因此&am…