「Linux 系统编程」文件权限与目录操作
1 文件和目录的 rwx 权限差异
-
文件权限
- r (读取): 允许查看文件内容
- w (写入): 允许修改文件内容
- x (执行): 允许将文件作为程序执行
-
目录权限
- r (读取): 允许 列出目录内容(需要 x 权限配合)
- w (写入): 允许在目录中 创建、删除和重命名文件(需要 x 权限配合)
- x (执行): 允许 访问目录中的文件及其元数据
2 目录操作函数
2.1 opendir() 打开目录
opendir()
用于打开一个已存在的目录,并返回一个目录流(directory stream)指针(DIR*
)。
-
函数原型
1
2
3
4#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name); -
参数
name
:要打开的目录的路径名。
-
返回值
- 成功时返回一个指向
DIR
结构体的指针(可视为目录流的句柄)。 - 失败时返回
NULL
,并设置相应的errno
。
- 成功时返回一个指向
-
代码示例
1
2
3
4
5
6DIR* dp;
dp = opendir("."); // 获取当前目录流
if (dp == NULL) {
perror("opendir failed");
exit(EXIT_FAILURE);
}
2.2 readdir() 读取目录
readdir()
从 opendir()
返回的目录流中 读取下一个目录项(entry)。
-
函数原型
1
2
3#include <dirent.h>
struct dirent *readdir(DIR *dirp); -
参数
dirp
:由opendir()
返回的目录流指针。 -
返回值
-
成功时返回一个指向
struct dirent
的指针,该结构体包含了目录项的信息(如文件名、inode号等)。 -
到达目录末尾 或 出错时 返回
NULL
。如果需要区分是错误还是到达末尾,需要在调用前将errno
设为 0,调用后如果返回NULL
且errno
被改变,则说明出错。
struct dirent
内容:1
2
3
4
5
6
7struct dirent {
long d_ino; // 文件的 inode 节点号
off_t d_off; // 目录项在目录文件中的偏移量
unsigned short d_reclen; // 当前目录项的长度
unsigned char d_type; // 文件类型
char d_name[NAME_MAX+1]; // 文件名(以 \0 结尾,最大 255 字符)
}; -
-
代码示例
1
2
3
4
5
6
7
8struct dirent *entry;
errno = 0; // 清空错误标志
while ((entry = readdir(dp)) != NULL) {
printf("File: %s\n", entry->d_name);
}
if (errno != 0) { // 检查循环是否因错误而退出
perror("readdir failed");
}
2.3 closedir() 关闭目录
closedir()
关闭由 opendir()
打开的目录流,释放相关资源。
-
函数原型
1
2
3
4#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp); -
参数
dirp
:要关闭的目录流指针。
-
返回值
- 成功时返回
0
。 - 失败时返回
-1
,并设置相应的errno
。
- 成功时返回
-
代码示例
1
2
3if (closedir(dp) == -1) {
perror("closedir failed");
}
2.4 实现列出目录下所有文件
可以使用 opendir()
, readdir()
, closedir()
来列出指定目录下所有文件,实现类似 ls
命令的功能:
1 |
|
3 实现递归遍历目录
3.1 整体思路
一开始判断命令行参数,获取查询的目录名称。 如果 argc == 1
,表示查询的是当前的目录 .
编写一个递归读取目录函数 recursive_read_dir
:
-
获取当前目录/文件路径信息,并格式化打印出路径信息。
-
判断 是否是目录:
- 如果是普通文件,则直接返回。
- 如果是目录,则遍历目录下的每个条目。对于遍历到的每个条目,构建完整的路径信息,递归调用函数
recursive_read_dir
。
3.2 实现代码
在实现代码中,为了让输出更加美观(比如类似于 tree
命令那种输出形式),在调用 recursive_read_dir
时另外传入了深度 depth
以及 判断是否是当前目录下最后一项 is_last
的参数,这样可以帮助相同深度的文件对齐显示。
具体细节可以直接看 ls-R.c
代码及注释:
1 |
|
测试结果如下:
「Linux 系统编程」文件权限与目录操作
https://marisamagic.github.io/2025/08/28/20250828/