🌦️ 文件管理

吞佛童子2022年10月10日
  • os
  • 文件管理
大约 8 分钟

🌦️ 文件管理

1. Linux 文件系统的组成

  • 文件系统的基本数据单位是 文件
  • 目的:对磁盘上的文件进行组织管理
  • 每个文件均包含 索引节点 [index node] & 目录项 [directory entry] 两部分

1) 索引节点 index node

  1. 作用
    • 存储文件的元信息
    • 元信息有哪些
      • inode 编号
      • 文件大小
      • 创建时间
      • 修改时间
      • 磁盘位置
      • 访问权限
    • 查看命令
      • stat 文件名
  2. inode 编号
    • 每个文件的 inode 号码是唯一的
    • 当移动 | 重命名文件时,inode 号码不变
  3. 根据文件名打开文件流程:
    • 根据文件名找到对应的 inode 号码
    • 根据 inode 号码获取 索引节点 信息,进行权限认证等操作
    • 根据 索引节点 信息,找到文件数据对应的 硬盘存储块位置,读出数据
  4. 硬盘格式化后,会被分成以下几个区域:
    • 超级块区
      • 存储文件系统的相关系统
      • 例如:块的大小、块的个数等
      • 文件系统被挂载时,加载进内存
    • 索引节点区
      • 存储索引节点相关信息
      • 每个索引节点一般为 128 B | 256 B
      • 对于硬盘上的数据,一般每 1KB | 2KB 均需要设置一个 索引节点
      • 为了加速查询,一般把索引数据缓存到内存中
      • 文件被访问时,加载进内存
    • 数据块区
      • 真正存储磁盘数据的位置
  5. 文件在磁盘中的存储
    • 磁盘读写的基本单位是 扇区,一个 扇区 == 512 B
    • 多个扇区组成一个逻辑块,由于扇区太小,所以实际每次读写以 逻辑块 为单位
    • Linux 中一个逻辑块 == 8 扇区 == 4 KB

2) 目录项 directory entry

  1. 目录
    • 在 Linux 中目录也是一种文件
    • 打开目录就是打开目录文件
    • 目录存储在磁盘
    • 目录中存放的是目录下的文件信息,例如 文件名、文件类型等
    • 具体文件信息通过 Hash 索引的方式存储,提高当前目录下文件查找效率,不过需要额外措施防止 hash 冲突
文件 inode 号文件类型文件名
95827目录 .
95828目录 ..
hash 索引数据块指针
3269874FE1236EA666
BF05674FE1236EA6103
…………
  1. 目录项
    • 为了避免频繁从磁盘中读取目录,内核将已经度过的目录用 目录项 这个数据结构缓存在内存中
    • 当下次读到相同目录时,直接从内存读,从而提高读取速度
    • 包含哪些内容
      • 文件的名称
      • 文件的类型
      • 索引节点指针
      • 与其他目录项的层级关系

2. 虚拟文件系统 VFS

1) 作用

  • 文件系统根据文件组成方式的不同,形成了不同的文件系统
  • 为了简化用户对文件系统的访问,在用户层 & 不同文件系统之间添加了 虚拟文件系统
  • 为用户提供统一接口

2) 常见文件系统

  1. 磁盘文件系统
    • 直接将数据存储在磁盘中
    • 例: Ext 2/3/4, XFS
  2. 内存文件系统
    • 数据存储在内存空间
    • 例: /proc & /sys
  3. 网络文件系统
    • 访问其他主机数据的文件系统
    • 例: NFS, SMB

3. 文件的存储

  • 文件系统的基本操作单位是 数据块,而非字节流等
  • 文件在磁盘中的存储分为以下两种存放方式:
    • 连续空间存储
    • 非连续空间存储

1) 连续空间存储

  1. 特点
    • 文件存放在连续的物理空间中,需要确定文件大小才可分配空间
  2. 优点
    • 读写效率高,磁盘一次寻址即可定位到文件
  3. 缺点
    • 易产生碎片化空间,空间利用率低
    • 文件扩容可能出现扩容失败,从而重新移动整个文件到新的位置

2) 非连续空间存储

  1. 链表
    • 隐式链表
      • 文件头包含 起始块 & 末尾块 的位置,且每个数据块中存储一个 next 指针,指向下一个数据块的位置
      • 在磁盘中依次查找所有数据库,速度较慢
      • 若某个数据块的 next 指针出现问题,会导致整个文件的损坏
      • 需要额外空间存储 next 指针
    • 显式链表
      • 将每个数据块的 next 指针存放在 文件分配表 中,文件分配表存在于 内存
      • 内存查找,比磁盘访问速度要快
      • 若磁盘很大,则文件分配表也很大,不适用于该情况
    • 特点
      • 不会产生磁盘碎片,空间利用率高
      • 动态扩容方便
      • 需要经过多次磁盘查找
  2. 索引
    • 实现:
      • 文件头包含 索引数据块 的指针
      • 每个文件均有自己的 索引数据块,索引数据块中存储该文件用到的所有数据块的 指针列表,索引数据块也存放于磁盘
      • 通过索引数据块中的指针列表,依次查找磁盘中的数据块
    • 特点:
      • 不会产生磁盘碎片,空间利用率高
      • 动态扩容方便
      • 支持顺序读写 & 随机读写
      • 需要经过多次磁盘查找
      • 不论文件多大,均有对应的 索引数据块;当文件占用数据块过多时,一个 索引数据块 可能存放不下,此时需要进行改进
      • 如何改进从而存放大数据?
        • 索引 + 链表
          • 在索引块中添加 next 指针,指向下一个索引数据块
        • 多级索引
          • 一个索引块中存放多个索引块的位置
          • 其他索引块中存放部分数据块指针

3) Unix 文件系统早期的文件存储方式

  • 文件头中包含 13 个指针
    • 10 个指向数据块的指针
      • 当文件占用数据块 <= 10 时,直接存放在这里,可以通过直接查找方式找到文件存储地址
    • 1 个指向 一级索引 的指针
      • 当文件占用数据块 > 10 && 只用 一级索引 就可以存放所有数据块 指针时,可以通过一级索引方式查找,一级索引中存放的是 所有数据块 指针列表
    • 1 个指向 二级索引 的指针
      • 当文件占用数据块可以用 二级索引 盛下时,二级索引 存放 所有索引块的指针列表,找到每个索引块后,可以得到该索引块中存放的 部分数据块 指针
    • 1 个指向 三级索引 的指针

4) 空闲空间的管理

  • 如何在存储文件时,确定哪里有空闲的数据块可以存储该文件

① 空闲表

  • 动态维护一张表
    • 表中每行存储空闲块的 开始位置 & 空闲长度
  • 当请求分配磁盘空间时,
    • 系统一次扫描空闲表中的行,直到找到满足条件的第一个空闲区间段
  • 当用户撤销一个文件时,
    • 回收文件系统空间
    • 顺序扫描空闲表,确定插入 | 更新位置,进行更新
  • 特点:
    • 适用于空闲区较少的情况

② 空闲链表

  • 将空闲数据块通过 next 指针连接
  • 当请求分配磁盘空间时,
    • 从链表头开始依次选取需要的空闲数据块
  • 特点:
    • 不支持随机访问
    • 适用于空闲区较少的情况

③ 位图法

  • 用二进制的一位表示磁盘中该数据块的使用情况
    • 当 == 0 时,说明该数据块空闲
    • 当 == 1 时,说明该数据块已被分配
  • 特点:
    • 简单方便
    • Linux 中采用该种方式,还用于 inode 空闲块的管理
  • 单个位图计算
    • 一个位图假设占用一个数据块,一个数据块 == 4 KB
    • 一个位图可以记录的数据块个数 == 4 KB = 4 * 1024 * 8 = 2 ^ 15
    • 一个位图可以记录的数据块总大小 == 2 ^ 15 * 4 KB = 127 MB
  • Linux 中采用块组的方式存放多个位图,每个块组记录一个位图大小的数据块
  • img_12.png

4. 其他问题

1) 硬连接 VS 软连接

  1. 硬连接
    • 文件别名不同,但是 inode 节点是同一个,因此指向的是同一个磁盘上的文件,通过任意一个文件修改内容,另一个读取到的是修改后的内容
    • 由于 inode 节点不可跨文件系统,因此硬连接的文件也是不可跨文件系统的
    • 当要删除 inode 节点对应的文件时,需要删除所有该 inode 节点对应的硬连接 & 源文件,才会彻底删除该文件
  2. 软连接
    • 基于源文件创建一个新文件,该新文件有自己的 inode 索引节点,只不过内容存放的是源文件的路径,类似于 Windows 下的快捷方式
    • 所以访问该新文件时,通过里面存放的源文件路径,间接访问到了源文件的内容
    • 由于 inode 节点是新的,因此可以跨文件系统
    • 删除源文件时,新文件仍存在,只不过通过文件中存放的路径,找不到源文件而已
  3. 命令
    • ln [选项] 源文件 目标文件
    • 选项包括:
      • -s 建立软连接,不加则建立硬连接
      • -f 若目标文件已存在,则删除目标文件后,再建立相应连接
上次编辑于: 2022/10/10 下午8:43:48
贡献者: liuxianzhishou