温馨提示×

centos readdir如何工作

小樊
44
2026-09-03 02:55:30
栏目: 智能运维

在 CentOS(以及所有 Linux 系统)中,readdir 通常是 C 库函数,用于读取目录内容。它底层依赖 Linux 内核的 getdents / getdents64 系统调用。下面从使用方式、工作原理、内核层面、CentOS 相关注意点几个方面说明。


一、readdir 是什么

readdir 是 POSIX 标准定义的目录读取函数:

#include <dirent.h>

struct dirent *readdir(DIR *dirp);
  • 用于逐个读取目录中的文件和子目录
  • 每次调用返回一个 struct dirent
  • 读取完毕返回 NULL

二、基本用法示例(CentOS / Linux 通用)

#include <stdio.h>
#include <dirent.h>

int main() {
    DIR *dir = opendir("/etc");
    if (!dir) {
        perror("opendir");
        return 1;
    }

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

    closedir(dir);
    return 0;
}

三、readdir 的内部工作流程

1️⃣ 用户态流程

  1. opendir(path)
    • 调用 open()
    • 返回 DIR *(内部包含文件描述符和缓冲区)
  2. readdir(dirp)
    • 如果缓冲区为空,调用内核
    • 否则从缓冲区取下一个 dirent
  3. 循环直到返回 NULL

2️⃣ 内核态流程(CentOS / Linux)

readdir 不是系统调用,真正工作的是:

readdir()  →  getdents64()  (内核)

不同文件系统实现不同:

  • ext4
    • 遍历 inode 中的目录项(dx directory)
  • xfs
    • B+ 树结构
  • tmpfs / proc / sysfs
    • 由内核动态生成目录项

内核返回的数据结构:

struct linux_dirent64 {
    ino64_t        d_ino;
    off64_t        d_off;
    unsigned short d_reclen;
    unsigned char  d_type;
    char           d_name[];
};

glibc 再把它转换成 struct dirent


四、struct dirent 结构(CentOS 常见)

struct dirent {
    ino_t          d_ino;
    off_t          d_off;
    unsigned short d_reclen;
    unsigned char  d_type;
    char           d_name[256];
};

d_type 示例:

含义
DT_REG 普通文件
DT_DIR 目录
DT_LNK 符号链接
DT_UNKNOWN 未知(某些 FS)

五、readdir 的重要特性

✅ 1. 顺序不保证

  • 目录项顺序由文件系统决定
  • 不要依赖排序

✅ 2. 包含 ...

  • 需要手动过滤
if (strcmp(entry->d_name, ".") == 0 ||
    strcmp(entry->d_name, "..") == 0)
    continue;

✅ 3. 不是线程安全

  • readdir 使用 DIR 内部状态
  • 多线程应使用 readdir_r(已废弃)或加锁

六、CentOS 特有注意点

1️⃣ glibc 版本差异

  • CentOS 7:glibc 2.17
  • CentOS 8 / Stream:glibc 2.28+

getdents64 一直可用


2️⃣ 大目录性能

  • readdir分批读取
  • 非常适合百万级文件目录
  • ls 轻量很多

3️⃣ /proc、/sys 是“虚拟目录”

  • readdir 读的是内核内存
  • 内容随系统状态变化

七、readdir vs readdir64

函数 说明
readdir 32 位 inode(老接口)
readdir64 64 位 inode(现代系统默认)

CentOS 实际使用的是 readdir64


八、总结一句话

在 CentOS 中,readdir 是 glibc 提供的目录遍历接口,底层通过 getdents64 系统调用从文件系统内核中分批读取目录项,适用于高效、稳定的目录扫描。

如果你愿意,我可以:

  • readdir 源码级别实现
  • 对比 readdir / scandir / nftw
  • 分析 CentOS 大目录性能问题
  • 给出 内核 getdents 调用示例

你想深入哪一部分?

0