UNIX高级编程 - 4 文件与目录

蒸汽
蒸汽
发布于 2025-04-09 / 23 阅读
0
0

UNIX高级编程 - 4 文件与目录

请注意:本笔记只摘录作者认为对自己比较有用或者陌生的知识,如果读者想要全面了解本书的细节,请自行阅读!!!

4.1.Overview

本章相比于3-文件IO来说,将描述文件系统的其他特征和文件的性质。

4.2 函数stat, fstat, fstatat, lstat

image.png

  • 一旦给出 pathname,stat 函数将返回与此命名文件有关的信息结构。

  • lstat与stat类似,但是如果pathname是链接文件,则返回链接文件的信息,不是链接引用文件的信息

  • fstatat是相对于当前目录的路径名返回文件统计信息,falg可以设置AT_SYMLINK_NOFOLLOW, 此时fstatat相当于lstat,如果设置成AT_FDCWD,并且pathname是相对路径则计算相对当前目录的pathname,如果pathname是绝对路径则忽略该flag

  • 第二个参数buf返回我们需要的文件信息数据结构指针 stat结构如下:

image.png image.png

timesepc结构类型按照秒和纳秒定义了时间,至少包括下面两个字段: image.png

4.3 文件类型

  • 普通文件

  • 目录文件

  • 块特殊文件:这种类型的文件提供对设备(如磁盘)带缓冲的访问,每次访问以固定长度为单位进行。

  • 字符特殊文件:这种类型的文件提供对设备不带缓冲的访问,每次访问长度可变。系统中所有设备要么是字符特殊文件,要么是块特殊文件

  • FIFO:这种类型的文件用于进程间的通信,有时候也称为命名管道named pipe

  • 套接字(socket)这种类型的文件用于进程间的网络通信。也可以用在一台宿主机上进程之间的非网络通信

  • 符号链接:这种类型的文件指向另一个文件。

文件类型信息 包含在stat结构的st_mode成员中,有如下几种宏的参数: image.png

tips:POSIX.1允许实现将进程间通信(IPC)对象(如消息队列和信号量)说明为文件。下图的宏可以用来从stat结构中确定IPC对象的类型。这些宏与图4-1中的不同,他们的参数并非st_mode,而是指向stat结构的指针

image.png

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值。此值包含实际设备的设备号


评论