请注意:本笔记只摘录作者认为对自己比较有用或者陌生的知识,如果读者想要全面了解本书的细节,请自行阅读!!!
4.1.Overview
本章相比于3-文件IO来说,将描述文件系统的其他特征和文件的性质。
4.2 函数stat, fstat, fstatat, lstat
一旦给出 pathname,stat 函数将返回与此命名文件有关的信息结构。
lstat与stat类似,但是如果pathname是链接文件,则返回链接文件的信息,不是链接引用文件的信息
fstatat是相对于当前目录的路径名返回文件统计信息,falg可以设置AT_SYMLINK_NOFOLLOW, 此时fstatat相当于lstat,如果设置成AT_FDCWD,并且pathname是相对路径则计算相对当前目录的pathname,如果pathname是绝对路径则忽略该flag
第二个参数buf返回我们需要的文件信息数据结构指针 stat结构如下:
timesepc结构类型按照秒和纳秒定义了时间,至少包括下面两个字段:
4.3 文件类型
普通文件
目录文件
块特殊文件:这种类型的文件提供对设备(如磁盘)带缓冲的访问,每次访问以固定长度为单位进行。
字符特殊文件:这种类型的文件提供对设备不带缓冲的访问,每次访问长度可变。系统中所有设备要么是字符特殊文件,要么是块特殊文件
FIFO:这种类型的文件用于进程间的通信,有时候也称为命名管道(named pipe)
套接字(socket)这种类型的文件用于进程间的网络通信。也可以用在一台宿主机上进程之间的非网络通信
符号链接:这种类型的文件指向另一个文件。
文件类型信息 包含在stat结构的st_mode成员中,有如下几种宏的参数:
tips:POSIX.1允许实现将进程间通信(IPC)对象(如消息队列和信号量)说明为文件。下图的宏可以用来从stat结构中确定IPC对象的类型。这些宏与图4-1中的不同,他们的参数并非st_mode,而是指向stat结构的指针。
4.7 函数access 和faccessat
![[Pasted image 20250328102142.png]]
用来测试用户对文件的访问权限
4.8 函数umask
用来屏蔽文件的某种访问的权限
例如: ![[Pasted image 20250328102609.png]]
tips:当前进程创建的umask对父进程不影响
![[Pasted image 20250328102716.png]]
4.12 文件空洞
文件空洞(file hole) 是指文件中未实际分配磁盘空间的一部分。也称为 稀疏文件(sparse file)。在文件的某些部分,虽然逻辑上存在数据(比如偏移量),但物理磁盘上并未真正写入任何内容,这部分就称为空洞。
🧠 通俗理解: 假设你有一个文件,总长度是 1GB,但是你只在开头写了 1KB,在结尾又写了 1KB,中间没有写任何数据。这个时候操作系统可能不会为中间那近 1GB 的“空白区域”真正分配磁盘空间。中间那部分就是“文件空洞”。
🔧 技术细节:
• 在类 Unix 系统中(如 Linux),文件是通过 inode 描述的,inode 中的 block 指向实际数据块。
• 如果文件中有一段没有写入内容的偏移区域,文件系统可以不分配实际的块,而只是记录“这段为空”。
• 读取空洞部分时,返回的通常是全零(\0)。
• 创建空洞常用 lseek() 系统调用跳过某些区域后写入数据。
4.13 文件截断
![[Pasted image 20250408094656.png]] 功能:将一个现有文件长度截断为length tips:如果以前的长度小于length,文件长度将增加,尾部加0
4.14 文件系统
本书只讨论UFS(传统的基于BSD的UNIX文件系统),UFS是以Berkeley快速文件系统为基础的。
磁盘、分区、文件系统结构如下:
![[Pasted image 20250408095428.png]]
![[Pasted image 20250408095554.png]]
在 图 中 有 两 个 ⽬ 录 项 指 向 同 ⼀ 个 i 节 点 。 每 个 i 节 点 中 都 有 ⼀ 个 链 接 计 数 , 其 值 是 指 向 该i 节 点 的 ⽬ 录 项 数 。 只 有 当 链 接 计 数 减 少 ⾄ 0 时 , 才 可 删 除 该 ⽂ 件 ( 也 就 是 可 以 释 放 该 ⽂件 占 ⽤ 的 数 据 块 ) 。 这 就 是 为 什 么 “ 解 除 对 ⼀ 个 ⽂ 件 的 链 接 ” 操 作 并 不 总 是 意 味 着 “ 释 放该 ⽂ 件 占 ⽤ 的 磁 盘 块 ” 的 原 因 。 这 也 是 为 什 么 删 除 ⼀ 个 ⽬ 录 项 的 函 数 被 称 之 为 u n l i n k⽽ 不 是 d e l e t e 的 原 因 。 在 s t a t 结 构 中 , 链 接 计 数 包 含 在 s t n l i n k 成 员 中 , 其 基 本系 统 数 据 类 型 是 n l i n k t 。 这 种 链 接 类 型 称 为 硬 链 接
另 外 ⼀ 种 链 接 类 型 称 为 符 号 链 接 ( s y m b o l i c l i n k ) 。符号链接是对一个文件的间接指针 符 号 链 接 ⽂ 件 的 实 际 内 容 ( 在 数 据 块中 ) 包 含 了 该 符 号 链 接 所 指 向 的 ⽂ 件 的 名 字 。 在 下 ⾯ 的 例 ⼦ 中 , ⽇ 录 项 中 的 ⽂ 件 名 是 3个 字 符 的 字 符 串 lib , ⽽ 在 该 ⽂ 件 中 包 含 了 7 个 字 节 的 数 据 u s x / l i b :
![[Pasted image 20250408100117.png]]
对于普通文件: ![[Pasted image 20250408100621.png]] 对于目录文件:
任何一个叶目录(不包含任何其他目录的目录)的链接总数总是2,来源于命名该目录的目录项已经该目录中的 . 项
如果加一个子目录,则本目录的链接计数要+1 (因为子目录中的..项) ![[Pasted image 20250408101154.png]]
4.15 link, linkat, unlink, unlinkat, remove函数
![[Pasted image 20250409084424.png]]
作用:进行文件==硬链接==和释放的函数
4.18 symlink ,symlinkat 函数
![[Pasted image 20250409084734.png]]
作用: 进行文件符号链接
4.19 文件的时间
2008年SUS支持提高stat结构中时间字段的精度从秒提升到纳秒。 ![[Pasted image 20250409084924.png]]
4.20 函数futims, utimensat , utimes
![[Pasted image 20250409085241.png]]
作用: 修改文件访问和时间
![[Pasted image 20250409085350.png]]
tips:注意,我们不能对状态更改时间st_ctim(i节点最近被修改的时间)指定一个值,因为调用utimes函数时,此字段会自动更新
4.24 设备特殊文件※
st_dev 与 st_rdev
每个文件系统所在的存储设备都由其主次设备号表示。设备号所用的数据类型是基本系统数据类型dev_t. 主设备号标识设备驱动程序, 有时编码为与其通信的外设;次设备号标识特定的子设备。例如一个磁盘驱动器有多个文件系统,他们的主设备号一样,但是次设备号就不同了
major 和 minor 我们通常使用的两个宏来访问主次设备号。
目前的操作系统很多采用32位整形存放设备号:8位为主设备号,24位为子设备号(或者64 = 32+32)
tips:
系统重与每个文件名关联的st_dev是文件系统的设备号,该文件系统包含了这一文件名以及对应的i节点
自由字符特殊文件和块文件才有st_rdev值。此值包含实际设备的设备号