操作系统复习(十)

文件的逻辑结构和物理结构

文件的逻辑结构物理结构是操作系统中两个核心概念,简单来说:逻辑结构是“用户看到的样子”,物理结构是“硬盘上存储的样子”

1. 逻辑结构

这是从应用程序和用户角度出发,看到的文件组织方式。它只关心数据如何被读取、写入和查找,不关心数据实际存放在磁盘的哪个角落。

  • 分类(按组织方式)
    • 流式结构(无结构):最常见的现代文件形式(如 .txt, .exe)。文件是一串连续的字节流,系统只记录文件的起始位置和总长度。内部有没有“记录”全靠应用程序自己去解析(比如Word文档内部有复杂格式,但对操作系统而言就是一堆字节)。
    • 记录式结构(有结构):常用于数据库或批处理文件。文件由多个固定长度或可变长度的“记录”组成(比如一张员工信息表,每条记录包含工号、姓名)。用户可以直接按“第几条记录”来存取。
  • 特点:方便用户编程和访问,具有高可移植性(只要应用兼容,换个存储介质逻辑不变)。

2. 物理结构

这是文件在磁盘、SSD等存储介质上的实际存放方式。它由操作系统文件系统(如NTFS、EXT4)管理,直接决定了磁盘的读写速度和存储空间的利用率。

  • 三大经典类型
    • 连续结构:文件数据存放在磁盘上一块连续的物理扇区中。就像在图书馆把书一本挨一本放在同一个书架上。优点是读写速度快(只需一次寻道);缺点是容易产生“磁盘碎片”,且文件大小很难动态扩展。
    • 链接结构(链式):文件数据存放在不连续的块中,每个数据块里存有一个指针,指向下一个块的地址。像“寻宝游戏”一样顺着线索找。优点是没有碎片,文件可随意增删;缺点是只能顺序读取(想读最后一块得从头遍历),且指针占用额外存储空间。
    • 索引结构:为每个文件建立一个“索引表”(如Unix的inode),表中记录了文件所有数据块的物理地址。优点是即能顺序存取也能随机存取(直接查表跳到第N块),且没有外部碎片;缺点是索引表本身需要额外占用空间。

3. 两者的核心区别与联系(重点)

维度 逻辑结构 物理结构
视角 用户/应用程序 操作系统/存储硬件
关注点 数据的语义、记录长度、访问方式 存储空间的利用率、寻道时间、I/O效率
稳定性 相对固定,由文件格式定义 随磁盘碎片整理、文件修改而随时变化
控制权 用户及上层软件可控 由底层文件系统驱动自动管理,用户无感

两者的桥梁(映射)
操作系统通过文件控制块(FCB,即目录项) 将逻辑结构与物理结构联系起来。当你双击一个文件时,系统读取目录项,找到物理结构的入口(如索引节点号),然后将磁盘上散落的物理块拼装起来,还原成一个连续的字节流(逻辑结构)呈现给你。


  • 逻辑结构目录和页码:你希望按“第一章、第二章”阅读,或者直接翻到第100页。这是你的使用习惯。
  • 物理结构印刷版面和纸张:打印机可能把第100页印在纸张的正面,第101页印在另一张纸的背面,甚至因为排版,第1章的最后一段被挪到了第3章的末尾页上(物理不连续)。但装订成册时,目录(索引)会指引你精准找到它们。

文件的存取方式

文件的存取方式(访问方式)是指操作系统如何根据用户命令定位并读写文件中的数据。它主要由文件的物理结构(如何存)和用户需求(如何用)共同决定。

在操作系统中,文件存取方式主要有以下三种

1. 顺序存取(Sequential Access)

这是最简单、最原始的存取方式。

  • 规则:对文件中的信息按从前到后的线性顺序进行读写。就像播放录音带或看一盒胶卷,必须从头开始,想读取第100条记录,必须跳过前99条。
  • 适用结构:通常配合链接结构(串联文件) 或连续结构使用。
  • 典型应用:批处理文件、磁带备份、日志文件的追加写入。
  • 优缺点:存取速度慢(不能跳跃),但对存储设备要求低,适合一次性全读/全写。

2. 直接存取(随机存取 / Direct Access)

这是现代磁盘文件最常用的方式。

  • 规则:用户可以直接指定文件的逻辑块号(如“读取第N条记录”或“读取第1024字节起的1024字节”),系统根据该编号直接跳转到对应位置读写,无需经过前面的数据。
  • 适用结构:必须配合连续结构(通过首地址+偏移量)或索引结构(查表跳转);绝不能配合纯链表式的串联结构(因为链表必须遍历)。
  • 典型应用:操作系统内核文件、数据库文件、编译器的目标代码(编译器经常需要回跳修改之前的地址)。
  • 优缺点:读写速度快,支持随意跳转,但要求存储介质支持寻道(如磁盘、SSD)。

3. 索引存取(Indexed Access / 按键存取)

这是对直接存取的一种高级扩展,建立在索引结构之上。

  • 规则:用户不提供物理块号,而是提供一条记录的关键字(Key)(如学号“2024001”、姓名“张三”)。系统先搜索该文件的索引表,找到关键字对应的逻辑块号,再通过直接存取去读取数据。
  • 适用结构:专用于索引结构的文件。
  • 典型应用:数据库系统、文件系统中的目录检索(根据文件名找inode)。
  • 优缺点:非常灵活,支持复杂查询,但维护索引表需要额外开销。

关联

存取方式 对应最佳的物理结构 是否支持“文件大小不固定”
顺序存取 串联结构(链接)、连续结构 串联支持,连续不支持
直接存取 连续结构索引结构 连续不支持,索引支持
索引存取 索引结构(必须有索引表) 支持(动态追加索引项即可)

考试万能口诀

  • 看到“磁带/顺序/从头开始”选 顺序存取
  • 看到“磁盘/跳跃/按块号”选 直接存取
  • 看到“关键字/查询/数据库”选 索引存取

成组链接法

好的!既然支持 Mermaid 流程图,我们直接用它来画,这样结构更清晰、专业,也符合 Markdown 的渲染习惯。我把**“静态存储结构”“动态分配/回收流程”**分开画,方便你理解和在考试中手绘简图。


1. 成组链接法静态结构图(超级块 + 磁盘分组)

下图展示的是内存超级块磁盘各分组之间的映射关系(假设每组容量为 3 个块,实际系统通常为 100)。

磁盘(外存)存储空间

内存(主存)

组 1

组 0

记录组0块号

记录组0块号

记录组0块号

组间链接指针

组间链接指针

组 2(最后一组)

块 300
(空闲数据块)

块 301
(空闲数据块)

块 302
(结束标志)
s_nfree = 0

超级块 Superblock
s_nfree = 3
s_free[0] = 100
s_free[1] = 101
s_free[2] = 102

块 100
(空闲数据块)

块 101
(空闲数据块)

块 102
(链指针块)
存放:200,201,202

块 200
(空闲数据块)

块 201
(空闲数据块)

块 202
(链指针块)
存放:300,301,302

图解说明

  • 超级块(内存) 只记录当前正在使用的一组(组0)的块号。
  • 组0的最后一块(块102) 不存用户数据,而是存放下一组(组1) 的块号列表。
  • 组1的最后一块(块202)又指向组2,以此类推,形成一条“链”。
  • 最后一组的最后一块(块302)存结束标志(s_nfree = 0),表示链尾。

2. 分配一个空闲块的流程(申请块)


(当前组只剩链指针块)

开始分配一个空闲块

检查超级块
s_nfree > 0 ?

从 s_free 数组尾部
取一个块号分配给用户

s_nfree 减 1

分配结束

将链指针块中存放的
下一组块号列表读入超级块
(覆盖原 s_free 数组)

将该链指针块
分配给用户(作为数据块)

关键点:绝大多数分配只需在内存超级块中操作,仅当当前组用完时才发生一次磁盘 I/O(读入下一组信息)。


3. 回收一个空闲块的流程(释放块)

开始回收空闲块 X

组是否已满?

将 X 加入 s_free 尾部

s_nfree 加 1

结束

将超级块内容写入 X

重置超级块 - 只存 X

关键点:回收时绝大多数只需修改内存超级块,仅当当前组已满时才发生一次磁盘 I/O(将旧组信息“备份”到新回收的块中,作为新的链指针块)。


Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐