温馨提示×

linux readdir版本差异吗

小樊
34
2026-10-11 12:46:02
栏目: 智能运维

在 Linux 下,readdir 相关的函数和“版本差异”主要涉及 不同标准/实现、不同年份的 POSIX 规范、以及 glibc 的不同版本。下面系统地给你梳理一下。


一、readdir 相关的几个函数

Linux 中常见的目录读取函数有:

  1. readdir()
  2. readdir_r()(线程安全版本,已废弃)
  3. readdir64() / readdir64_r()(大文件 / 64 位 inode)
  4. getdents() / getdents64()(系统调用层)

二、主要“版本差异”来源

1. POSIX 标准版本差异

POSIX.1-2001 / SUSv3

  • 定义了 readdir()
  • readdir() 不是线程安全的
  • 使用静态缓冲区(同一线程多次调用会覆盖)

示例:

struct dirent *readdir(DIR *dirp);

POSIX.1-2008

  • 仍保留 readdir()
  • 不推荐使用 readdir_r()
  • 明确 readdir() 在单线程内顺序调用是安全的

2. readdir vs readdir_r(重要差异)

readdir(传统)

struct dirent *readdir(DIR *dirp);
  • 简单
  • 非线程安全(但 glibc 内部已加锁)
  • 推荐使用 ✅

readdir_r(已废弃)

int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
  • 设计用于线程安全
  • 实际存在问题(buffer 大小不确定)
  • glibc 2.34+ 标记为废弃
  • 新代码不要用 ❌

3. glibc 版本差异(重点)

glibc 2.0 ~ 2.33

  • readdir() 内部使用锁
  • readdir_r() 可用但不推荐

glibc 2.34(2021)

  • 移除 readdir_r() 的实现
  • readdir() 成为唯一推荐方式
  • 编译时可能报:
    warning: readdir_r is deprecated
    

✅ 结论:

现代 Linux 程序应只使用 readdir()


4. 32 位 vs 64 位(readdir vs readdir64)

在 32 位系统上:

函数 说明
readdir 32 位 inode
readdir64 64 位 inode(支持大文件系统)

64 位系统:

  • readdir 实际已是 readdir64

宏定义常见:

#define readdir readdir64

5. 底层系统调用差异

用户态:

readdir()

内核态:

getdents()
getdents64()  // 现代 Linux

getdents64 支持:

  • 64 位 inode
  • 更丰富的文件类型

三、推荐用法(现代 Linux)

DIR *dir = opendir(".");
struct dirent *entry;

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

closedir(dir);

✅ glibc 2.34+ ✅ POSIX.1-2008 ✅ 线程安全(单线程顺序调用)


四、常见误区

❌ “readdir_r 更安全”
✅ 实际反而更容易出错

❌ “必须加锁才能用 readdir”
✅ glibc 已内部加锁

❌ “不同 Linux 发行版 readdir 行为不同”
✅ 只要 glibc 版本一致,行为一致


如果你愿意,我可以:

  • 对比 某个具体 glibc 版本
  • 讲 readdir 内部实现
  • 给 线程安全目录遍历示例
  • 分析 某个老代码为什么用 readdir_r

你更关心哪一块?

0 踩