温馨提示×

debian readdir和opendir关系

小樊
44
2026-09-13 09:08:26
栏目: 智能运维

在 Debian(以及所有类 Unix/Linux 系统)中,opendir 和 readdir 是 用来遍历目录内容的一对配套函数,通常配合 closedir 使用。它们都来自 POSIX 标准,定义在 <dirent.h> 中。

下面从关系、使用流程、原理和示例几个方面说明。


一、基本关系

函数 作用
opendir 打开一个目录,返回一个目录流(DIR *)
readdir 从目录流中读取下一个目录项(文件/子目录)
closedir 关闭目录流,释放资源

关系一句话总结:

opendir 打开目录,readdir 不断读取目录项,最后用 closedir 关闭。


二、函数原型(Debian / glibc)

#include <dirent.h>

DIR *opendir(const char *name);
struct dirent *readdir(DIR *dirp);
int closedir(DIR *dirp);

三、典型使用流程

DIR *dir = opendir("/path/to/dir");
if (!dir) {
    perror("opendir");
    return -1;
}

struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
    printf("%s\n", entry->d_name);
}

closedir(dir);

四、它们是如何配合工作的

  1. opendir

    • 打开目录文件(如 /home)
    • 在内核中建立目录流
    • 返回 DIR *(类似 FILE *)
  2. readdir

    • 每次调用返回 一个目录项
    • 内部维护“当前读取位置”
    • 返回 NULL 表示:
      • 读到目录末尾
      • 或出错(需配合 errno)
  3. closedir

    • 释放 DIR * 相关资源
    • 不调用会导致文件描述符泄漏

五、struct dirent 常见字段

struct dirent {
    ino_t          d_ino;     // inode 号
    off_t          d_off;     // 偏移
    unsigned short d_reclen;  // 记录长度
    unsigned char  d_type;    // 文件类型
    char           d_name[];  // 文件名
};

示例判断类型:

if (entry->d_type == DT_DIR) {
    // 目录
}

六、与系统调用的关系(Debian 底层)

在 Debian(glibc)中:

  • opendir → 内部调用 open() + getdents64()
  • readdir → 缓冲并解析 getdents64() 返回的数据
  • closedir → close()

可以用 strace 查看:

strace ls /tmp

七、常见注意点

  1. 会读到 . 和 ..

    if (strcmp(entry->d_name, ".") == 0 ||
        strcmp(entry->d_name, "..") == 0)
        continue;
    
  2. 不是递归的

    • readdir 只读当前目录
    • 递归遍历需自己写
  3. 线程安全

    • readdir 不是线程安全
    • 多线程请用 readdir_r(已废弃)或 readdir + 锁

八、一句话总结

在 Debian 中,opendir 用来“打开目录”,readdir 用来“逐个读取目录里的文件”,二者是生产者—消费者式的一对函数,必须配合使用,最后用 closedir 收尾。

如果你愿意,我也可以:

  • 给你一个递归遍历目录的完整 C 示例
  • 对比 readdir vs scandir
  • 讲 Debian 下目录权限对 opendir 的影响

0 踩