文件管理(五)—— 文件的基本操作

前言

文件系统提供六种基本操作:创建、删除、打开、关闭、读、写。其他复杂操作均由这些基本操作组合完成。

1. 创建文件

系统调用参数:所需外存空间大小、文件存放路径、文件名。

系统做的两件事:

  1. 根据申请的大小,用存储空间管理策略(空闲表法/位视图法等)在外存中分配磁盘块;
  2. 在指定路径的目录表中插入一条新的目录项(FCB),记录文件名、存放位置等信息。

2. 删除文件

系统调用参数:文件存放路径、文件名。

系统做的三件事:

  1. 根据路径找到对应目录表,再按文件名找到目录项,读取文件占用的磁盘块信息;
  2. 按存储空间管理策略回收文件占用的磁盘块;
  3. 删除目录表中该文件的目录项。

3. 打开文件

在大多数操作系统中,对文件进行读写之前必须先调用 open。

系统调用参数:文件存放路径、文件名、操作类型(只读 / 读写等)。

系统做的两件事:

  1. 根据路径在外存中找到目录表,检查用户的访问权限(权限信息记录在目录项中),若无权限则拒绝;
  2. 权限合法后,将目录项复制到内存的打开文件表中,并将该表项的索引号(文件描述符)返回给用户。

打开文件时不会将文件的实际数据读入内存,只是将目录项信息载入打开文件表。

打开文件表

内存中存在两张打开文件表:

系统打开文件表 进程打开文件表
数量 全局唯一一张 每个进程一张
记录内容 所有正在被进程使用的文件信息 该进程已打开的文件信息
特有字段 打开计数器(记录当前有几个进程打开了该文件) 读写指针(记录当前读写进行到的位置)、访问权限(该进程打开时申请的操作类型)

进程打开文件表中包含一个指向系统表对应表项的索引号,多个进程打开同一文件时各自持有独立的读写指针和权限,但共享系统表中的同一条记录。

打开计数器的作用:系统在删除文件前会先查系统打开文件表,若打开计数器 > 0(有进程正在使用),则拒绝删除(即 Windows 中「文件正在被占用,无法删除」的情形)。

4. 关闭文件

系统做的三件事:

  1. 删除进程打开文件表中该文件对应的表项,回收相关内存缓冲区等资源;
  2. 将系统打开文件表中对应表项的打开计数器减 1;
  3. 若打开计数器减为 0,说明无进程再使用该文件,则删除系统打开文件表中的该表项。

5. 读文件

读写操作必须在文件已打开的前提下进行。

系统调用参数:文件描述符(打开文件表索引号)、读入数据量(如 1 KB)、目标内存地址。

系统操作:根据进程打开文件表中的读写指针找到外存对应位置,将指定大小的数据读入用户指定的内存区域,并更新读写指针。

只有 read 操作才会将文件的实际数据从外存读入内存。

6. 写文件

系统调用参数:文件描述符、写回数据量(如 1 KB)、源内存地址。

系统操作:从用户指定的内存区域读取指定大小的数据,写回到写指针所指向的外存位置,并更新写指针。

写文件与读文件流程对称,二者操作参数结构完全相同。

7. 小结

操作 是否访问外存目录 是否将文件数据读入内存 关键点
创建 写目录 分配磁盘块 + 插入目录项
删除 读+删目录 回收磁盘块 + 删除目录项
打开 读目录 否(仅复制目录项到打开文件表) 权限检查;返回文件描述符
关闭 打开计数器 -1;归零时删系统表项
否(查打开文件表) 依据读写指针定位外存数据
否(查打开文件表) 否(内存→外存) 依据写指针写回外存

最容易混淆的点:

  • 打开文件 ≠ 读文件:open 只把目录项复制到内存打开文件表,不读取文件数据;read 才真正将文件数据从外存读入内存。
  • 读写操作时用户只需提供文件描述符(打开文件表索引号),无需再提供文件名或路径。
  • 文件描述符即进程打开文件表的索引号(序号),也称为"文件句柄"。
相关推荐
mifengxing10 小时前
操作系统 文件系统
笔记·操作系统·计算机408
用户9385156350711 小时前
TypeScript 高级类型 + CSS 三列布局:从类型体操到样式工程的进阶之路
css·面试·typescript
Scabbards_13 小时前
面试Leetcode - Heap 堆
java·leetcode·面试
黄敬峰14 小时前
🐳 Docker 从入门到实战:一次搞定容器化 + Nginx 反向代理
面试
程序员清风14 小时前
专业再升级!程序员专属显示器明基RD280UG上手实测!
java·后端·面试
six_15 小时前
C# 上位机(持续更新中)
前端·面试·c#
mifengxing16 小时前
文件逻辑结构、物理结构与磁盘空闲存储空间管理
大数据·linux·运维·操作系统·计算机408
码匠许师傅16 小时前
【C++ 面试真题】聊聊 C++ 的序列容器
java·c++·面试
东华万里18 小时前
第40篇C++核心基础与工程实践:从底层逻辑到避坑指南
开发语言·c++·面试·大学生专区
wangjialelele20 小时前
动态规划DP经典题型总结(Java、C++):路径、子数组、子序列、背包问题详解
java·c++·算法·面试·动态规划·代理模式