文件系统机制
POSIX 文件系统与目录机制总结
一、文件系统核心机制
- 树状目录结构
- 根目录:以
/
为起点,所有文件和目录形成层次化树状结构。 - 路径表示:
- 绝对路径:从根目录开始(如
/home/user/file.txt
)。 - 相对路径:从当前工作目录(CWD)开始(如
../documents/
)。
- 绝对路径:从根目录开始(如
-
特殊目录:
.
:当前目录。..
:父目录。
-
文件类型
POSIX 定义多种文件类型,可通过stat()
的st_mode
字段判断:
类型 | 标识宏 | 说明 |
---|---|---|
普通文件 | S_ISREG() |
文本、二进制等常规数据文件。 |
目录 | S_ISDIR() |
包含其他文件或子目录的容器。 |
符号链接 | S_ISLNK() |
指向其他文件路径的快捷方式。 |
字符设备/块设备 | S_ISCHR() /S_ISBLK() |
硬件设备抽象(如终端、磁盘)。 |
FIFO(命名管道) | S_ISFIFO() |
进程间通信的先进先出队列。 |
套接字 | S_ISSOCK() |
网络或进程间通信的端点。 |
- Inode 元数据
- 唯一标识:每个文件对应一个 inode,存储元信息(权限、大小、时间戳等)。
- 获取方式:通过
stat()
、fstat()
、lstat()
获取struct stat
结构体。 - 关键字段:
二、目录操作机制
-
目录遍历
- 核心函数:
DIR *opendir(const char *name)
:打开目录,返回目录流指针。struct dirent *readdir(DIR *dirp)
:读取目录项,返回dirent
结构体。
closedir(DIR *dirp)
:关闭目录流。
- 示例:递归遍历目录树需自行实现(结合
S_ISDIR
判断子目录)。
- 核心函数:
-
目录创建与删除
int mkdir(const char *pathname, mode_t mode)
:创建目录,权限由mode
指定(受umask
影响)。int rmdir(const char *pathname)
:删除空目录。- 注意:删除非空目录需递归删除其内容(POSIX 未提供直接支持,需手动实现)。
三、文件链接机制
-
硬链接(Hard Link)
- 机制:通过
link(const char *oldpath, const char *newpath)
创建,多个文件名指向同一 inode。 - 特性:
- 不能跨文件系统(同一设备)。
- 删除原文件不影响硬链接(inode 引用计数减 1)。
- 机制:通过
-
符号链接(Symbolic Link)
- 机制:通过
symlink(const char *target, const char *linkpath)
创建,存储目标文件路径。 - 特性:
- 可跨文件系统。
- 目标文件删除后,符号链接成为“悬空链接”(
ENOENT
错误)。
- 读取内容:使用
readlink()
获取链接指向的实际路径。
- 机制:通过
四、权限与所有权
-
权限控制
- 权限位:
- 用户(Owner)、组(Group)、其他(Others)的读(
r
)、写(w
)、执行(x
)权限。 - 特殊权限位:
setuid
:执行时以文件所有者权限运行。setgid
:目录中新文件继承组 ID。- 粘滞位(Sticky Bit):仅文件所有者可删除/重命名(如
/tmp
目录)。
- 用户(Owner)、组(Group)、其他(Others)的读(
- 函数:
chmod(const char *path, mode_t mode)
:修改权限。umask(mode_t mask)
:设置进程的文件创建权限掩码(默认屏蔽位)。
- 权限位:
-
所有权管理
- 函数:
chown(const char *path, uid_t owner, gid_t group)
:修改文件所有者和组。lchown()
:修改符号链接自身所有权(而非目标文件)。
- 函数:
五、文件系统操作函数
-
路径解析
char *realpath(const char *path, char *resolved_path)
:解析绝对路径,消除符号链接。int access(const char *path, int mode)
:检查路径访问权限(F_OK
、R_OK
、W_OK
、X_OK
)。
-
工作目录管理
char *getcwd(char *buf, size_t size)
:获取当前工作目录。int chdir(const char *path)
:切换当前工作目录。
-
文件删除
int unlink(const char *pathname)
:删除文件(减少 inode 引用计数,引用为 0 时释放)。int remove(const char *pathname)
:等价于unlink()
(文件)或rmdir()
(目录)。
六、挂载与文件系统管理
-
挂载机制
- 挂载点:通过
mount()
将设备或虚拟文件系统附加到目录树(具体实现依赖操作系统)。 - 卸载:
umount()
或umount2()
解除挂载。
- 挂载点:通过
-
文件系统信息
int statvfs(const char *path, struct statvfs *buf)
:获取文件系统统计信息(如块大小、总空间、可用空间)。
七、关键设计思想
-
统一抽象
- 所有资源(文件、设备、管道等)均以文件形式呈现,简化操作接口。
-
权限分离
- 通过用户/组权限和特殊位实现精细的访问控制。
-
软硬链接分离
- 硬链接保证数据持久性,符号链接提供灵活性。
-
可扩展性
- 支持多种文件系统类型(如 ext4、FAT、NFS)通过挂载机制无缝集成。
八、总结
机制 | 核心功能 | 关键函数/操作 |
---|---|---|
目录结构 | 树状层次化管理文件 | opendir /readdir /mkdir |
文件类型 | 区分普通文件、目录、设备等 | stat() /S_ISDIR() |
链接机制 | 硬链接共享数据,符号链接跨文件系统 | link() /symlink() /readlink() |
权限控制 | 用户/组/其他权限 + 特殊位 | chmod() /chown() |
文件系统管理 | 挂载、空间查询、路径解析 | mount() /statvfs() /realpath() |
- 应用场景:
- 文件搜索工具:结合目录遍历与权限检查。
- 备份系统:利用硬链接减少存储冗余。
- 多用户环境:通过权限位隔离数据访问。