UNIX 文件系统基本操作( 二 )
例如,许多 Unix 包含一个 d_type 成员和一些附加常量,这样一来,您无需额外的 stat() 调用就可以检查目录条目的类型 。除了减少另外的系统调用之外,这种不可移植的扩展还减少了从文件系统获取更多元数据的开销非常高的访问操作 。众所周知,在大多数 UNIX 上,stat() 函数的执行速度非常慢 。
获取文件信息
除了获取目录中条目的名称之外,您可能还需要一些附加信息,以确定下一步要进行的操作 。至少,仅根据目录条目的名称,您无法辨别文件条目 。
stat() 函数会将特定文件的相关信息填入 struct stat 结构中,如果您获得的是文件描述符而不是文件名,那么作为替代,您可以使用 fstat() 函数 。如果您想能够检测出符号链接,那么可以对文件名使用 lstat() 。
与 readdir() 返回的 struct dirent 不同,struct stat 具有相当多的标准的、必需的成员:
【UNIX 文件系统基本操作】st_mode——文件权限(用户、其他用户、组)和标志
st_ino——文件序列号
st_dev——文件设备号
st_nlink——文件连接计数
st_uid——所有者用户 ID
st_gid——所有者组 ID
st_size——以字节表示的文件大小(针对普通文件)
st_atime——最后的访问时间
st_mtime——最后的修改时间
st_ctime——文件的创建时间
对 st_mode 成员使用 S_*() 宏,这样就可以找出您所处理的目录条目的类型:
S_ISBLK(mode)——是否为块特殊文件?(通常是某种基于块的设备)
S_ISCHR(mode)——是否为字符特殊文件?(通常是某种基于字符的设备)
S_ISDIR(mode)——是否为目录?
S_ISFIFO(mode)——是否为管道或 FIFO 特殊文件?
S_ISLNK(mode)——是否为符号链接?
S_ISREG(mode)——是否为普通文件?
众所周知,在大多数文件系统上,stat() 函数的执行速度非常慢,所以如果您打算在将来再次使用该信息,可能需要对其进行缓存 。
关于符号链接的说明
通常,您并不关心符号链接 。如果对符号链接调用 stat(),那么您将获取该链接所指向的文件的相关信息 。这和用户的体验是一致的,因为控制与该文件交互的是目标文件的权限,而不是符号链接本身 。
有些应用程序,如 ls 和备份程序,需要能够显示链接文件本身的相关信息,例如它所指向的文件 。当您使用 lstat() 来代替 stat() 时,以及当您出于特定的目的而需要获取符号链接本身的相关信息,而不是直接与其链接的文件打交道时,情况也是这样的 。
将其组合在一起
既然已经学习了如何使用 readdir() 和 stat() 来查找目录中的条目,那么让我们来看看演示这些函数的一些实际代码 。
这里所介绍的代码将浏览命令行中指定的一个或多个目录,并显示在该目录中找到的每个条目的相关信息 。当它找到另一个目录时,它会对该目录进行同样的处理 。对于符号链接,将显示其目标文件,并且还将显示普通文件的大小 。将忽略特殊文件 。
如清单 2 所示,这个简单的演示应用程序中包含了各种 Header 文件 。程序的开始块中包含了大多数程序中使用的标准部分,并且后面的四项是在该程序中使用 readdir() 和 stat() 所必需的 。
清单 2. Header 和常量
#include
#include
#include
#include
#include
#include
#include
#include
#include
process_Directory() 函数(开始于清单 3,结束于清单 6)读取了指定的目录,并显示了每个条目的相关信息 。opendir() 返回的 DIR 指针与 fopen() 返回的 FILE 指针类似,它是一个用于跟踪目录流的操作系统特定的对象,您应该忽略其具体内容 。
推荐阅读
- UNIX 新手指南,第 3 部分:正则表达式
- UNIX 新手指南,第 2 部分: vi 文本编辑器
- UNIX 新手指南: 一些很好的 Shell 诀窍
- 使用 UNIX System V IPC 机制共享应用程序数据
- 利用 UNIX 脚本来管理 DS4000 磁盘阵列系统
- 对话 UNIX,第 13 部分: 另外十种命令行组合
- UNIX 生产力技巧
- UNIX 新手指南,第 1 部分: 文件维护工具
- 使用 UNIX find 命令的高级技术
- 对话 UNIX: 更多 shell 脚本技术