在 Linux 下使用 readdir 兼容 32 位程序,核心问题在于不是函数本身不兼容,而是程序编译环境、ABI 和文件偏移类型(off_t / ino_t)是否一致。下面分情况说清楚。
readdir 本身是否区分 32 / 64 位?readdir 是 POSIX 接口,不区分 32/64 位struct dirent *readdir(DIR *dirp);
真正区分的是:
readdir vs readdir64struct dirent vs struct dirent64off_t 是 32 位还是 64 位(_FILE_OFFSET_BITS)ino_t / off_t 是 32 位(legacy)在 32 位系统或未开启大文件支持时:
struct dirent {
ino_t d_ino; // 32 位
off_t d_off; // 32 位
...
};
如果目录中 inode > 2^32 或使用了 64 位文件系统,会导致:
readdir 返回 NULLerrno = EOVERFLOW✅ 解决方法(推荐)
#define _FILE_OFFSET_BITS 64
#include <dirent.h>
或者直接用:
readdir64()
struct dirent64
readdir_FILE_OFFSET_BITS=64readdir → readdir64
只要你定义了:#define _FILE_OFFSET_BITS 64
#define _FILE_OFFSET_BITS 64
#include <dirent.h>
#include <stdio.h>
int main() {
DIR *dir = opendir(".");
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
printf("%s\n", entry->d_name);
}
closedir(dir);
return 0;
}
编译:
gcc -m32 -D_FILE_OFFSET_BITS=64 test.c
| 函数 | 适用 |
|---|---|
| readdir | 默认(可能被重定向) |
| readdir64 | 明确 64 位 inode |
| readdir_r | 已废弃 |
| getdents64 | 系统调用级 |
file a.out
ldd a.out
getconf LONG_BIT
如果看到:
errno = EOVERFLOW
基本就是 32 位 inode 不够用。
Linux
readdir兼容 32 位的关键:
- 32 位程序必须开
_FILE_OFFSET_BITS=64- 或直接使用
readdir64- 不要混用 32/64 位库
如果你有具体场景(交叉编译 / 容器 / 老系统 / 嵌入式),我可以给你更针对性的方案。