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

前言

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

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 才真正将文件数据从外存读入内存。
  • 读写操作时用户只需提供文件描述符(打开文件表索引号),无需再提供文件名或路径。
  • 文件描述符即进程打开文件表的索引号(序号),也称为"文件句柄"。
相关推荐
Moment32 分钟前
Harness Engineering 为什么是 AI Coding 的工程底座 ❓❓❓
前端·后端·面试
利威尔xu1 小时前
2026-11-08-Go-defer-panic-recover面试
面试·golang
CoderYanger6 小时前
Java EE 进阶:8.MyBatis 操作数据库(入门)(第二弹)
java·数据库·spring boot·spring·面试·java-ee·mybatis
wo_jack18 小时前
C++ 入门笔记(十六):第16课 vector 模拟实现十问十答 —— 从三指针到迭代器失效
c++·后端·面试·stl·vector
聪明的笨猪猪20 小时前
AI应用架构选型:架构师的核心决策困境与权衡
经验分享·面试·架构
疯华整猫1 天前
被杀掉之后:我把 Android 的「唤起 + 常驻」重做了一遍
前端·面试·架构
nice_lcj5201 天前
Java 并发容器入门:ConcurrentHashMap、CopyOnWriteArrayList、阻塞队列
java·面试·并发编程·阻塞队列·concurrenthashmap·copyonwritearraylist
岁月宁静1 天前
AI 应用开发工程师简历怎么写:HR 初筛、技术复筛、面试追问,三道关卡各看什么?
人工智能·python·面试
Dream it possible!2 天前
LeetCode 面试经典 150_多维动态规划_交错字符串(97_C++_中等)
算法·leetcode·面试·动态规划
yeccheng2 天前
MySQL 索引超详解:从底层 B+ 树到面试高频考点
java·开发语言·jvm·mysql·面试