跳转至

9 File System

9.1 File Concept

文件是存储某种介质上的(如磁盘、光盘、SSD等)并具有文件名的一组相关信息的集合

文件的属性是操作系统用于管理文件的重要信息,通常存储在磁盘上的目录结构中。这些信息被称为文件元数据(file metadata)

  • 名称(Name):唯一的人类可读标识,用户用来识别文件。这是唯一以人类可读形式保存的信息。
  • 标识符(Identifier) 文件系统内部使用的唯一标签(如数字ID),用于在系统中唯一标识该文件。
  • 类型(Type) 用于支持多种文件类型的系统,例如区分文本、图像、可执行程序等。
  • 位置(Location) 指向文件在存储设备上实际存放位置的指针(如块号或簇地址)。
  • 大小(Size) 当前文件所占用的字节数或存储空间大小。
  • 保护(Protection) 控制哪些用户或进程可以对文件进行读取、写入和执行操作,实现访问控制。
  • 时间、日期和用户标识(Time, date, and user identification) 包括创建时间、修改时间、访问时间以及拥有者信息,用于安全保护、权限管理和使用监控。

操作系统通过一组基本操作来管理文件。常见的文件操作包括:创建(Create)、写入(Write)、读取(Read)、在文件内重新定位(Reposition within file)、删除(Delete)和截断(Truncate)。

其中,打开文件(Open(\(F_i\)))是指在磁盘的目录结构中查找对应的文件条目 \(F_i\),并将该文件的元数据或内容加载到内存中,以便后续访问;关闭文件(Close(\(F_i\)))则是将内存中该文件条目的内容同步回磁盘的目录结构,确保数据一致性并释放相关资源。

为了有效管理已打开的文件,操作系统需要维护若干关键数据信息:

  • 首先是文件指针(File pointer),它指向每个进程当前读写操作的位置,确保不同进程对同一文件的访问不会相互干扰;
  • 其次是文件打开计数(File-open count),用于记录该文件被打开的次数,只有当所有进程都关闭该文件时,系统才会将其从打开文件表中移除,防止资源泄漏;
  • 第三是文件在磁盘上的位置(Disk location of the file),即文件实际存储位置的缓存信息,便于快速访问;
  • 最后是访问权限(Access rights),记录每个进程对该文件的访问模式(如读、写、执行等),以实现安全控制。

关于文件类型,从操作系统角度来看,系统支持多种文件类型。Unix(如Linux、Mac OS)和Windows都支持普通文件和目录文件;此外,Unix系统还支持字符设备文件、块设备文件和符号链接文件等特殊文件类型。其中,普通文件又可分为可执行文件、文本文件等多种形式,用于存储用户数据或程序代码。

从用户角度,文件类型通常通过文件扩展名来识别。在Windows系统中,文件扩展名具有特殊含义,操作系统会根据扩展名自动关联程序并决定如何处理文件;而在Unix类系统(如Linux、Mac OS)中,文件扩展名仅是一种约定,不被系统强制使用,文件类型主要由内容或权限等属性决定。


文件的内部结构(逻辑结构)可分为三类:

  • 第一类是无结构的字节流(None),将文件视为连续的字节或字符序列,如流文件结构;
  • 第二类是简单记录结构,包括按行组织、固定长度记录和可变长度记录,适用于结构化数据存储;
  • 第三类是复杂结构,如格式化文档或可重定位的加载文件,还可以是树型等层次结构

9.2 Access Methods

文件的存取方法主要有三种:

  • 顺序存取(Sequential Access),按先后顺序读写数据,支持“读下一个”、“写下一个”、“重置”等操作,且在最后一次写入后不能回读;

  • 直接存取(Direct Access),通过指定相对块号 \(n\) 实现对任意位置的读写,支持“读第 \(n\) 块”、“写第 \(n\) 块”、“定位到第 \(n\) 块”等操作,灵活性高;

  • 此外还有索引顺序存取(Indexed Sequential Access),结合了顺序与直接存取的优点,通过索引结构实现高效访问。

9.3 Directory Structure

目录是文件系统的核心组织单元,它是一个包含所有文件相关信息的节点集合。这些节点与实际的文件(F1, F2, ..., Fn)共同存储在磁盘上,

为了数据安全,整个目录结构和文件内容都会定期备份到磁带等外部存储介质上。

物理磁盘可以被划分为多个逻辑分区(也称为小磁盘或切片),每个分区可以独立地应用RAID技术以增强可靠性,或者选择不使用文件系统(raw模式)而直接使用。当一个分区被格式化后,它就成为一个卷(volume),该卷会通过设备目录或卷内容表来维护其自身的文件系统元数据。

目录上可以执行多种基本操作,包括:

  • 搜索文件(Search for a file),用于查找指定文件的位置;
  • 创建文件(Create a file),在目录中添加新文件;
  • 删除文件(Delete a file),从目录中移除文件;
  • 列出目录内容(List a directory),显示目录中所有文件和子目录的信息;
  • 重命名文件(Rename a file),修改文件的名称;
  • 遍历文件系统(Traverse the file system),即按照一定的结构顺序访问和处理目录及其子目录中的所有文件

设计目录结构时需考虑三个主要目标:

  • 一是效率,即能快速定位文件;
  • 二是命名灵活性,允许多个用户使用相同文件名或一个文件拥有多个别名;
  • 三是分组能力,能将具有相似属性的文件(如所有Java程序)逻辑地组织在一起,方便管理。

单级目录结构是最简单的形式,整个系统只有一个根目录,所有用户的文件都存放于此。这种结构存在严重的命名冲突问题(不同用户不能有同名文件)和分组困难问题(所有文件混杂在一起)

二级目录结构为每个用户创建一个独立的子目录(通常以其用户名命名),从而解决了命名冲突问题,因为不同用户的同名文件位于各自的目录下。系统通过路径名(如 user_name/file_name)来唯一标识文件,并提高了搜索效率,但仍然缺乏对文件进行更细粒度分组的能力

树型目录结构是一种层次化的组织方式,允许用户创建任意深度的子目录,形成一棵倒置的树。它不仅继承了二级目录的优点,还提供了强大的分组能力,并引入了“当前目录”(工作目录)的概念,使得用户可以通过相对路径方便地访问文件。

在树型结构中,文件和目录可以通过绝对路径(从根目录开始)或相对路径(从当前目录开始)来访问。用户在当前目录下可以直接创建新文件或子目录(如使用 mkdir 命令)。删除一个目录会同时删除其下的整个子树,这要求用户操作时格外谨慎。

无环图(DAG)目录结构在树型结构的基础上增加了共享能力,允许多个目录项指向同一个文件或子目录(即硬链接)。这带来了别名(aliasing)问题,即一个文件有多个名称。为了解决删除共享文件后可能出现的悬空指针问题,系统通常采用“表项保留计数”(如Unix/Linux中的硬链接计数)机制来跟踪引用数量。

普通图结构目录进一步扩展了共享能力,允许符号链接(软链接)等机制,但这可能导致目录结构中出现循环(cycles)。为防止因循环导致遍历无限进行或无法释放空间等问题,系统需要采取措施,例如限制链接只能指向文件而非子目录、定期运行垃圾回收,或在每次创建新链接时运行环路检测算法。

9.4 File System Mounting

一个文件系统在被访问之前,必须先执行挂载(mounting)操作。未挂载的文件系统(例如一个独立的磁盘分区)需要被关联到现有文件系统目录树中的一个特定位置,这个位置被称为挂载点(mount point)。

在Unix/Linux系统中:

  • mount 命令用于将存储设备或文件系统挂载到系统中的某个目录,使用户能够访问该设备的内容。
  • umount 命令用于卸载已挂载的文件系统,确保数据的完整性并释放资源。
  • 挂载和卸载操作是 Linux 系统中磁盘管理的基础,正确使用这些命令能够帮助你有效地管理存储设备,避免数据丢失和文件系统损坏。

9.5 File Sharing

文件共享是多用户系统中的重要功能,旨在实现资源的有效利用和协作。在操作系统中,通过用户ID(User IDs)可以唯一标识每个用户,从而为不同用户设置个性化的文件访问权限和保护机制;同时,组ID(Group IDs)允许将用户组织成不同的组,便于对一组用户赋予统一的访问权限,简化管理。

对于单个用户而言,可以通过符号链接(Unix类系统)、硬链接(Unix类系统)或快捷方式(Windows)来创建文件的别名,方便快速访问。

在多用户环境中,文件共享尤为必要,通常通过基于权限的保护机制来控制访问。在分布式系统中,文件可以在网络上进行共享,其中网络文件系统(NFS)是一种常见的、广泛使用的分布式文件共享方法,它允许客户端透明地访问服务器上的文件,如同访问本地文件一样。

9.6 Protection

文件保护机制允许文件所有者或创建者控制谁可以对文件执行何种操作。常见的访问类型包括读取(Read)、写入(Write)、执行(Execute)、追加(Append)、删除(Delete)和列出(List)。

在Unix/Linux系统中,通常通过访问控制列表(ACL)结合用户组来实现权限管理,将用户分为三类:文件所有者(owner)、所属组成员(group)和公众(public),分别赋予不同的读、写、执行权限(用rwx表示,数字7=111, 6=110, 1=001)。

例如,chmod 761 game 表示所有者可读写执行,组内成员可读写,其他用户仅可执行;chgrp G game 则用于将文件“game”归属到名为G的组。

评论区

对你有帮助的话请给我个赞和 star => GitHub stars
欢迎跟我探讨!!!