「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/