在 Debian(Linux) 下使用 readdir 时,所谓“避免错误”,通常是指 避免程序崩溃、返回错误码或读取异常。下面从 常见错误、正确用法、注意事项 三个方面说明。
如果 opendir() 失败,readdir() 一定会出错。
DIR *dir = opendir(path);
if (dir == NULL) {
perror("opendir");
return -1;
}
⚠️ 常见错误:
readdir() 在 到达目录尾 时返回 NULL,这不是错误,但很多人误以为是。
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
...
}
✅ 正确做法:
NULL + errno == 0 → 正常结束NULL + errno != 0 → 真正出错如果在 readdir() 过程中:
可能出现:
EBADF✅ 避免方法:
DIR * 不是线程安全的
❌ 错误示例:
// 两个线程同时 readdir(dir)
✅ 正确做法:
opendir()readdir() 出错时,errno 可能被设置。
errno = 0;
struct dirent *entry = readdir(dir);
if (entry == NULL) {
if (errno != 0) {
perror("readdir");
}
}
#include <stdio.h>
#include <dirent.h>
#include <errno.h>
int list_dir(const char *path)
{
DIR *dir = opendir(path);
if (!dir) {
perror("opendir");
return -1;
}
errno = 0;
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
printf("%s\n", entry->d_name);
}
if (errno != 0) {
perror("readdir");
closedir(dir);
return -1;
}
closedir(dir);
return 0;
}
d_name 不是无限长
char path[PATH_MAX];
snprintf(path, sizeof(path), "%s/%s", dirpath, entry->d_name);
if (strcmp(entry->d_name, ".") == 0 ||
strcmp(entry->d_name, "..") == 0)
continue;
即使能 opendir(),某些文件也可能无法 stat() / open()
✅ 建议:
readdir_r(已废弃)❌ 不推荐
scandir(适合一次性读取)struct dirent **list;
int n = scandir(path, &list, NULL, alphasort);
✅ 好处:
✅ 必须做
opendir() 检查返回值readdir() 判断 NULL + errnoclosedir()✅ 避免
DIR *errno如果你愿意,可以贴出你的 具体代码或报错信息,我可以帮你逐行分析。