在 C 语言里,读取目录内容通常离不开 readdir。很多入门示例只给出几行代码,但真正写到项目里时,开发者往往还需要搞清楚它和 opendir、closedir 怎么配合,返回的数据该怎么理解,以及哪些边界问题不能忽略。下面就按“打开目录、逐项读取、完整示例、使用注意点”的顺序梳理一遍,方便你快速判断这套写法能否直接用于自己的程序。
readdir 用来做什么
readdir 的作用是读取目录中的条目,它定义在 dirent.h 头文件中。实际使用时,它通常不会单独出现,而是和目录打开、关闭这两个步骤配套使用:
- 先用
opendir打开目录,拿到一个DIR *指针; - 再反复调用
readdir,逐个读取目录项; - 读取结束后,用
closedir关闭目录。
先包含需要的头文件
在示例程序中,先引入下面几个头文件:
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>其中,和目录读取直接相关的是 dirent.h;其余头文件分别用于标准输入输出、退出流程等常见操作。
如何用 opendir 打开目录
读取目录前,第一步是调用 opendir。如果路径有效且可访问,它会返回一个 DIR 类型指针;如果失败,则返回 NULL,这时应立即做错误处理。

DIR *dir = opendir("/path/to/directory");
if (dir == NULL) {
perror("opendir");
exit(EXIT_FAILURE);
}这里的关键点很直接:opendir 成功后才能继续调用 readdir。如果目录不存在、权限不足,或者路径本身有问题,程序都应该在这个阶段停止或转入异常处理分支。
如何循环读取目录条目
目录成功打开后,就可以在循环里调用 readdir。它每次返回一个 struct dirent *,指向当前读取到的目录项;当没有更多条目时,返回 NULL。
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
printf("%sn", entry->d_name);
}这一段代码的核心,是通过 entry->d_name 取得目录项名称并输出。也就是说,最基础的目录遍历其实就是不断读取、不断处理当前条目,直到 readdir 返回 NULL 为止。
读取完成后记得关闭目录
目录遍历结束后,要调用 closedir 释放目录句柄。这个步骤虽然简单,但不应省略。
closedir(dir);如果程序中频繁打开目录却不关闭,长期运行时就可能积累资源占用问题。
完整示例代码
把前面的几个步骤合在一起,就是一个最小可运行版本:
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
int main() {
DIR *dir = opendir("/path/to/directory");
if (dir == NULL) {
perror("opendir");
exit(EXIT_FAILURE);
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
printf("%sn", entry->d_name);
}
closedir(dir);
return 0;
}如果你只是想快速验证 readdir 的基本行为,这段代码已经够用。把 "/path/to/directory" 替换成实际目录路径后,就能看到程序依次输出该目录下的条目名。
使用 readdir 时要注意什么
1. 返回值检查不能省略
原始示例里已经对 opendir 做了判断。实际开发中,readdir 的返回结果同样应该结合上下文判断,避免把读取结束和异常情况混为一谈。

2. 不需要手动释放 dirent
readdir 返回的 dirent 结构体不需要手动 free。按原文说明,它是由内核分配的,因此这里不要额外做释放操作。
3. 多线程环境要考虑线程安全
需要注意的是,readdir 不是线程安全的。如果程序在多线程环境里共享目录流,应该自行加入适当的同步机制。
4. 返回结果可能包含符号链接
读取到的目录条目中,可能包含符号链接指向的文件或目录。如果后续还要继续判断类型、递归处理或访问目标路径,这一点要提前考虑进去。
小结
在 C 语言中使用 readdir 的流程并不复杂,核心就是:包含 dirent.h、用 opendir 打开目录、在循环中读取 dirent 条目、最后调用 closedir 收尾。真正影响代码是否稳妥的,主要还是错误处理、线程安全以及对目录项类型的理解,这些细节补齐后,目录遍历代码才更适合放进实际项目。













