理解文件系统

        我们知道文件可以分为磁盘文件和内存文件,内存文件前面我们已经谈过了,下面我们来谈谈磁盘文件。

目录

一、引入"块"概念

解析 stat demo.c 命令输出

基本信息

设备信息

索引节点信息

权限信息

时间戳

二、引入"分区"概念

1、在Linux系统中,可通过以下命令查看磁盘分区信息

2、磁盘实现分区

3、磁盘格式化

三、引入"inode"概念

解析 ls -l 命令输出内容

各字段详细解析

特殊情况的表示

解析 ls -li 命令输出

Inode号 (第1列)

注意

请注意

目前大家可能还存在两个疑问


一、引入"块"概念

        硬盘是典型的"块"设备。操作系统在读取硬盘数据时,并非逐个扇区读取(这样效率太低),而是通过一次性连续读取多个扇区来实现,这个连续读取的单位称为"块"(block)。

        每个硬盘分区都被划分为若干个"块"。"块"的大小在格式化时确定且不可更改,最常见的大小是4KB(即连续八个扇区组成一个"块")。"块"是文件存取的最小单位。

stat 文件名

解析 stat demo.c 命令输出

stat 命令用于显示文件或文件系统的详细状态信息。以下是 demo.c 文件的详细信息解析:

基本信息

  • 文件名: 'demo.c'

  • 大小: 182 字节

  • 占用块数: 8 个块 (通常每个块512字节,所以占用约4KB空间)

  • IO块大小: 4096 字节 (文件系统块大小)

  • 类型: 普通文件 (regular file)

设备信息

  • 设备号: fd01h/64769d (主设备号fd01h,次设备号64769d)

索引节点信息

  • Inode号: 655967

  • 硬链接数: 1 (表示没有其他硬链接指向此文件)

权限信息

  • 访问权限: 0664 (-rw-rw-r--)

    • 所有者(hmz): 读写权限(rw-)

    • 所属组(hmz): 读写权限(rw-)

    • 其他用户: 只读权限(r--)

  • 所有者: UID 1000 (用户名hmz)

  • 所属组: GID 1000 (组名hmz)

时间戳

  • 最后访问时间(Access): 2025-07-16 23:18:34.624613705 +0800

  • 最后修改时间(Modify): 2025-07-16 23:18:26.954651585 +0800 (文件内容最后修改时间)

  • 最后状态变更时间(Change): 2025-07-16 23:18:26.955651450 +0800 (文件元数据如权限等最后变更时间)

  • 创建时间(Birth): - (不支持或未记录)

注意:

  • 磁盘可视为一个三维数组,我们将其抽象为一维数组处理,数组下标对应LBA(Logical Block Address),每个元素代表一个扇区
  • 每个扇区都有对应的LBA地址,8个扇区组成一个块,可以根据LBA计算出块地址
  • LBA与块号的转换关系:
    • 已知LBA求块号:块号 = LBA / 8
    • 已知块号求LBA:LBA = 块号 * 8 + n(n表示块内扇区序号)


二、引入"分区"概念

        磁盘作为典型的块设备,通常以512字节的扇区为基本单位。以512GB磁盘为例,其包含超过十亿个扇区。

        实际上,磁盘可以被划分为多个分区(partition)。分区编辑器将磁盘划分为若干逻辑区域,不同分区可存储特定类型的目录和文件。分区越多,文件分类管理就越细致。以Windows系统为例,你可能有一块物理磁盘并将其划分为C、D、E盘,这些盘符就代表不同的分区。从本质上说,分区就是对硬盘进行格式化的一种方式。

1、在Linux系统中,可通过以下命令查看磁盘分区信息

ls /dev/vda* -l

2、磁盘实现分区

        在Linux系统中,所有设备都以文件形式存在,那么如何实现分区呢?分区的最小单位是柱面,我们可以通过指定柱面编号来进行分区,具体操作就是设置每个分区的起始和结束柱面编号。

        为了更直观地理解,我们可以将硬盘上的柱面(分区)展开,想象成一个平面示意图,如下图所示:

注意:

当满足以下条件时:

  • 所有柱面大小一致(即每个柱面包含相同数量的磁道)

  • 每个磁道的扇区数相同(即"扇区个位一致")

那么计算分区大小和LBA地址可以简化为:

  1. 分区大小计算:

    分区大小 = (结束柱面号 - 起始柱面号 + 1) × 每柱面扇区数 × 扇区大小
  2. LBA计算:

    某位置的LBA = 起始柱面的LBA + (柱面偏移 × 每柱面扇区数) + 磁头偏移 × 每磁道扇区数 + 扇区偏移 - 1

3、磁盘格式化

        在完成磁盘分区后,还需要进行格式化操作。格式化是对磁盘分区进行初始化的过程,这一操作会清除分区内所有现有文件。

简而言之,格式化就是在各个分区中写入相应的管理信息。

        其中,写入的管理信息是什么是由文件系统决定的,不同的文件系统格式化时写入的管理信息是不同的,常见的文件系统有EXT2、EXT3、XFS、NTFS等。 会在后面的博客中进行讲解!


三、引入"inode"概念

        在Linux系统中,文件内容与元数据是分开存储的。这种存储元数据的结构称为inode。由于系统中可能存在大量文件,每个文件属性集都需要一个唯一标识符,即inode编号。

        简而言之,inode就是文件属性的集合。Linux系统中几乎所有文件都拥有自己的inode。为了有效区分系统中的众多inode,每个inode都被分配了唯一的编号。

        正如之前所述,文件由数据和属性两部分组成。当我们使用ls -l命令时,不仅能看到文件名,还能查看文件的元数据(即属性信息)。

ls -l

解析 ls -l 命令输出内容

    ls -l 是 Linux/Unix 系统中常用的命令,用于以长格式显示文件和目录的详细信息。以下是典型输出的解析:

各字段详细解析

  1. 文件类型和权限(第1列)
    由10个字符组成,例如 -rwxr-xr--

    • 第1个字符:文件类型

      标识符文件类型说明
      -普通文件常规文件,如文本、二进制文件等
      d目录文件夹,包含其他文件或子目录
      l符号链接快捷方式,指向另一个文件或目录(如 link -> target
      c字符设备文件按字符流访问的设备(如终端 /dev/tty
      b块设备文件按数据块访问的设备(如硬盘 /dev/sda
      s套接字文件进程间通信的套接字文件(如 MySQL 的 /var/run/mysqld/mysqld.sock
      p命名管道文件先进先出(FIFO)管道,用于进程间通信(如 mkfifo 创建的文件)
    • 第2-4字符:所有者权限(u)

    • 第5-7字符:组权限(g)

    • 第8-10字符:其他用户权限(o)

    • 权限字符:

      字符权限类型说明
      r读权限允许查看文件内容(文件)或列出目录内容(目录)
      w写权限允许修改文件内容(文件)或在目录中创建/删除文件(目录)
      x执行权限允许执行文件(程序/脚本)或进入目录(目录)
      sSUID/SGIDSUID(所有者位置):以文件所有者权限执行
      SGID(组位置):以文件所属组权限执行或继承父目录的组权限
      t粘滞位仅对目录有效,用户只能删除自己拥有的文件(如 /tmp 目录)
  2. 硬链接数(第2列)
    显示指向该文件/目录的硬链接数量。目录通常至少有2个链接(自身和.)。

  3. 所有者(第3列)
    文件/目录的属主用户名。

  4. 所属组(第4列)
    文件/目录的属组名。

  5. 大小(第5列)

    • 普通文件:显示字节大小

    • 目录:显示目录元数据占用的空间(通常4096字节)

  6. 最后修改时间(第6-8列)
    显示文件/目录的最后修改时间,格式通常为:

    • 月份(如Jun)

    • 日期(如12)

    • 时间(如14:30)

    • 如果文件修改时间超过6个月,会显示年份而非时间

  7. 文件名(最后一列)
    文件或目录名称。如果是符号链接,会显示 linkname -> targetname

特殊情况的表示

  • SUID/SGID权限

    • rwsr-xr-x(所有者x位置变为s表示SUID)

    • rwxr-sr-x(组x位置变为s表示SGID)

  • 粘滞位

    • rwxr-xr-t(其他用户x位置变为t)

  • 大小时单位显示
    使用 -lh 选项时会以K/M/G等易读单位显示大小

ls -l 用于读取磁盘上的文件信息并显示详细列表:

除了通过这种方式读取信息,还可以使用 stat 命令查看更详细的内容:

        这里我们需要思考一个问题:既然文件数据都存储在"块"中,那么显然还需要一个地方来存储文件的元信息(属性信息),比如创建者、创建日期、文件大小等。这个存储文件元信息的区域就叫做inode,中文译名为"索引节点"。

ls -li

解析 ls -li 命令输出

    ls -li 命令结合了 -i (显示inode号) 和 -l (长格式) 选项,提供比普通 ls -l 更详细的信息。以下是完整解析:

Inode号 (第1列)

  • 唯一标识文件系统内的文件

  • 示例:1234567

  • 特点:

    • 每个文件/目录有唯一inode号

    • 硬链接共享相同inode号

    • 删除文件实际上是减少inode的链接计数

        每个文件都对应一个inode,其中存储着该文件的相关信息。要理解inode的概念,我们需要先深入了解文件系统的工作原理。

注意

  • Linux系统中文件采用属性与内容分离的存储机制
  • Linux通过inode结构存储文件属性,每个文件对应一个独立的inode
  • inode中包含唯一的标识符,称为inode号

一个文件的 inode 属性具体是什么样呢?我们来到源码中看看对应的结构:

/** Structure of an inode on the disk (ext2文件系统的磁盘inode结构)*/
struct ext2_inode {/* 基础信息 */__le16 i_mode;          /* 文件类型和权限 (rwx) */__le16 i_uid;           /* 所有者UID低16位 */__le32 i_size;          /* 文件大小(字节) *//* 时间戳(Unix时间戳格式) */__le32 i_atime;         /* 最后访问时间 */__le32 i_ctime;         /* 创建时间 */__le32 i_mtime;         /* 最后修改时间 */__le32 i_dtime;         /* 删除时间 *//* 所有权信息 */__le16 i_gid;           /* 所属组GID低16位 */__le16 i_links_count;   /* 硬链接计数 */__le32 i_blocks;        /* 占用块数(512字节为单位) */__le32 i_flags;         /* 文件标志(如不可修改、压缩等) *//* 操作系统特定数据1 */union {struct {__le32 l_i_reserved1;} linux1;struct {__le32 h_i_translator;} hurd1;struct {__le32 m_i_reserved1;} masix1;} osd1;/* 数据块指针 */__le32 i_block[EXT2_N_BLOCKS];  /* 直接/间接块指针(共15个) *//* 扩展属性 */__le32 i_generation;    /* 文件版本(用于NFS) */__le32 i_file_acl;      /* 文件ACL块指针 */__le32 i_dir_acl;       /* 目录ACL块指针 */__le32 i_faddr;         /* 碎片地址 *//* 操作系统特定数据2 */union {struct {__u8  l_i_frag;       /* 碎片编号 */__u8  l_i_fsize;      /* 碎片大小 */__u16 i_pad1;__le16 l_i_uid_high;   /* 所有者UID高16位 */__le16 l_i_gid_high;   /* 所属组GID高16位 */__u32  l_i_reserved2;} linux2;struct {__u8  h_i_frag;__u8  h_i_fsize;__le16 h_i_mode_high;__le16 h_i_uid_high;__le16 h_i_gid_high;__le32 h_i_author;} hurd2;struct {__u8  m_i_frag;__u8  m_i_fsize;__u16 m_pad1;__u32 m_i_reserved2[2];} masix2;} osd2;
};/** 数据块相关常量*/
#define EXT2_NDIR_BLOCKS  12  /* 直接块数量 */
#define EXT2_IND_BLOCK    (EXT2_NDIR_BLOCKS)      /* 一级间接块索引 */
#define EXT2_DIND_BLOCK   (EXT2_IND_BLOCK + 1)    /* 二级间接块索引 */
#define EXT2_TIND_BLOCK   (EXT2_DIND_BLOCK + 1)   /* 三级间接块索引 */
#define EXT2_N_BLOCKS     (EXT2_TIND_BLOCK + 1)   /* 总块指针数(15个) */

查看源码后,我们可以知道inode这个数据结构中包含了很多很多的文件属性!!!

请注意

  • 文件名属性不包含在inode数据结构中
  • inode大小通常为128字节或256字节,后续讨论中将统一采用128字节
  • 不同文件的内容大小可以各不相同,但其属性大小始终相同

目前大家可能还存在两个疑问

  1. 我们已经知道硬盘是典型的"块"设备,操作系统读取硬盘数据的基本单位是"块"。这些"块"作为硬盘分区下的结构,它们是如何在分区上有序分布的?系统又是如何快速定位到这些"块"的呢?

  2. 前面提到的存储文件属性的inode,它们又是如何被组织存放的?

文件系统正是为了解决这些问题而设计的!后面将会讲解文件系统的相关知识!!!

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

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

相关文章

基于paddleDetect的半监督目标检测实战

基于paddleDetect的半监督目标检测实战前言相关介绍前提条件实验环境安装环境项目地址使用paddleDetect的半监督方法训练自己的数据集准备数据分割数据集配置参数文件PaddleDetection-2.7.0/configs/semi_det/denseteacher/denseteacher_ppyoloe_plus_crn_l_coco_semi010.ymlPa…

计算机网络:(十)虚拟专用网 VPN 和网络地址转换 NAT

计算机网络:(十)虚拟专用网 VPN 和网络地址转换 NAT前言一、虚拟专用网 VPN1. 基础概念与作用2. 工作原理3. 常见类型4. 协议对比二、NAT:网络地址转换1. 基础概念与作用2. 工作原理与类型3. 优缺点与问题4. 进阶类型三、VPN 与 N…

数位 dp

数位dp 特点 问题大多是指“在 [l,r][l,r][l,r] 的区间内,满足……的数字的个数、种类,等等。” 但是显然,出题人想要卡你,rrr 肯定是非常大的,暴力枚举一定超时。 于是就有了数位 dp。 基本思路 数位 dp 说白了…

Selector的用法

Selector的用法 Selector是基于lxml构建的支持XPath选择器、CSS选择器&#xff0c;以及正则表达式&#xff0c;功能全面&#xff0c;解析速度和准确度非常高 from scrapy import Selectorbody <html><head><title>HelloWorld</title></head>&…

Netty封装Websocket并实现动态路由

引言 关于Netty和Websocket的介绍我就不多讲了,网上一搜一大片。现如今AI的趋势发展很热门,长连接对话也是会经常接触到的,使用Websocket实现长连接,那么很多人为了快速开发快速集成就会使用spring-boot-starter-websocket依赖快速实现,但是注意该实现是基于tomcat的,有…

行为型设计模式:解释器模式

解释器模式 解释器模式介绍 解释器模式使用频率不算高&#xff0c;通常用来描述如何构建一个简单“语言”的语法解释器。它只在一些非常特定的领域被用到&#xff0c;比如编译器、规则引擎、正则表达式、SQL 解析等。不过&#xff0c;了解它的实现原理同样很重要&#xff0c;能…

SaTokenException: 未能获取对应StpLogic 问题解决

&#x1f4dd; Sa-Token 异常处&#xff1a;未能获取对应StpLogic&#xff0c;typeuser&#x1f9e8; 异常信息 cn.dev33.satoken.exception.SaTokenException: 未能获取对应StpLogic&#xff0c;typeuser抛出位置&#xff1a; throw new SaTokenException("未能获取对应S…

Web前端性能优化原理与方法

一、概述 1.1 性能对业务的影响 大部分网站的作用是&#xff1a;产品信息载体、用户交互工具或商品流通渠道。这就要求网站与更多用户建立联系&#xff0c;同时还要保持良好的用户黏性&#xff0c;所以网站就不能只关注自我表达&#xff0c;而不顾及用户是否喜欢。看看网站性…

第十八节:第六部分:java高级:注解、自定义注解、元注解

认识注解自定义注解注解的原理元注解常用的两个元注解代码&#xff1a; MyTest1&#xff08;注解类&#xff09; package com.itheima.day10_annotation;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.Retent…

北京科技企业在软文推广发稿平台发布文章,如何精准触达客户?

大家好&#xff01;我是你们的老朋友&#xff0c;今天咱们聊聊北京科技企业如何通过软文推广发稿平台精准触达目标客户这个话题。作为企业营销的老司机&#xff0c;我深知在这个信息爆炸的时代&#xff0c;如何让你的品牌声音被目标客户听到是多么重要。下面就让我来分享一些实…

UE蒙太奇和动画序列有什么区别?

在 UE5 中&#xff0c;Animation Sequence&#xff08;动画序列&#xff09;和 Animation Montage&#xff08;动画蒙太奇&#xff09;虽然都能播放骨骼动画&#xff0c;但它们的定位、功能和使用场景有较大区别&#xff1a;1. 概念定位Animation Sequence&#xff08;动画序列…

Nordic打印RTT[屏蔽打印中的<info> app]

屏蔽打印中的 app Nordic原装的程序答应是这样的,这个有" app"打印,因为习惯问题,有时候也不想打印太多造成RTT VIEW显示被冲点,所以要把" app"去掉:这里把prefix_process函数调用屏蔽到,主要涉及到nrf_log_hexdump_entry_process和nrf_log_std_entry_proc…

Python基础和高级【抽取复习】

1.Python 的深拷贝和浅拷贝有什么区别&#xff1f; 浅拷贝【ls.copy()】&#xff1a; 将列表的不可变对象【值】复制一份&#xff0c;同时引用其中的可变对象【列表】&#xff0c;共用一个内存地址 深拷贝【lscopy.deepcopy(list)】&#xff1a; 完全的复制原可变对象&#xff…

TinyPiXOS组件开发(一):开发规范、组件开发方法介绍,快速上手组件开发,创造各种有趣的UI组件!

本文将通过实现一个点击切换进度的电量指示灯组件和exampleGUI组件库介绍如何基于TinyPiXOS开发新组件。主要内容包括组件开发规范、自定义组件开发和组件库开发三部分。 组件开发规范 命名规范 采用tp开头命名组件类&#xff0c;名称具备易读性。 目录规范 头文件放置 in…

主流熔断方案选型指南

主流熔断方案选型1. Netflix Hystrix (经典但已停止维护)适用场景&#xff1a;传统Spring Cloud项目&#xff0c;需要快速集成熔断功能优点&#xff1a;成熟稳定&#xff0c;社区资源丰富与Spring Cloud Netflix套件无缝集成提供熔断、降级、隔离等完整功能缺点&#xff1a;已停…

Django中get()与filter()对比

在 Django 中&#xff0c;get() 和 filter() 是 QuerySet API 中用于检索数据的两个核心方法&#xff0c;它们的功能和使用场景有明显区别。以下是详细对比&#xff1a; 1. 核心区别特性get()filter()返回值单个对象&#xff08;模型实例&#xff09;查询集&#xff08;QuerySe…

MySQL锁(一) 概述与分类

1.1 MySQL锁的由来 客户端发往 MySQL 的一条条 SQL 语句&#xff0c;实际上都可以理解成一个个单独的事务&#xff08;一条sql语句默认就是一个事务&#xff09;。而事务是基于数据库连接的&#xff0c;每个数据库连接在 MySQL 中&#xff0c;又会用一条工作线程来维护&#x…

PyTorch里的张量及张量的操作

张量的简介 张量是多重线性映射在给定基下的坐标表示&#xff0c;可视为向量和矩阵的泛化。 0 维张量&#xff1a;标量&#xff08;如 5&#xff09;1 维张量&#xff1a;向量&#xff08;如 [1, 2, 3]&#xff09;2 维张量&#xff1a;矩阵&#xff08;如 [[1, 2], [3, 4]]&…

向量数据库Faiss vs Qdrant全面对比

Faiss vs Qdrant 全面对比表 向量数据库是一种相对较新的方式,用于与来自不透明机器学习模型(如深度学习架构)派生的抽象数据表示进行交互。这些表示通常被称为向量或嵌入(embeddings),它们是用于训练机器学习模型完成诸如情感分析、语音识别、目标检测等任务的数据的压…

2025年AIR SCI1区TOP,缩减因子分数阶蜣螂优化算法FORDBO,深度解析+性能实测

目录1.摘要2.蜣螂优化算法DBO原理3.改进策略4.结果展示5.参考文献6.代码获取7.算法辅导应用定制读者交流1.摘要 传统DBO存在探索与开发能力失衡、求解精度低以及易陷入局部最优等问题。因此&#xff0c;本文提出了带有缩减因子分数阶蜣螂优化算法&#xff08;FORDBO&#xff0…