在 Debian(以及所有 Linux 系统)上,readdir() 返回“空值”通常有几种不同层面的含义,需要区分你是说:
readdir() 返回 NULL(函数层面的“空”)readdir() 返回了目录项,但名字为空 / 只有 . 和 ..readdir() 读不到下面按常见原因逐一说明。
readdir() 返回 NULL 的常见原因opendir() 成功DIR *dir = opendir("/some/path");
if (!dir) {
perror("opendir");
return;
}
如果路径不存在、权限不足,opendir() 返回 NULL,之后 readdir() 当然也返回 NULL。
✅ 检查:
如果目录本身没有任何文件:
struct dirent *ent;
while ((ent = readdir(dir)) != NULL) {
...
}
循环一次都不执行,readdir() 直接返回 NULL,这是正常行为。
readdir() 返回 NULL 不代表出错,也可能是正常结束:
while ((ent = readdir(dir)) != NULL) {
printf("%s\n", ent->d_name);
}
// 到这里 readdir 返回 NULL,是正常结束
判断是否出错应使用 errno:
errno = 0;
ent = readdir(dir);
if (!ent && errno != 0) {
perror("readdir");
}
. 和 ..这是完全正常的:
.
..
如果你只想看“真实文件”:
if (strcmp(ent->d_name, ".") == 0 ||
strcmp(ent->d_name, "..") == 0)
continue;
Linux 中以 . 开头的文件是隐藏文件:
.config
.bashrc
ls 需要加 -a 才能看到。
✅ 检查:
mount | grep your_path
ls -la /mount/point
某些服务(如 nginx、php、docker)被限制访问目录。
✅ 检查:
dmesg | grep apparmor
readdir vs readdir64在老代码或交叉编译中:
readdir()readdir64()混用可能导致异常。
✅ 推荐:
#define _GNU_SOURCE
#include <dirent.h>
opendir() 后,目录被 rm -rfmount --bind 覆盖#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <errno.h>
int main(int argc, char *argv[]) {
const char *path = argv[1];
DIR *dir = opendir(path);
if (!dir) {
perror("opendir");
return 1;
}
struct dirent *ent;
errno = 0;
while ((ent = readdir(dir)) != NULL) {
if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
continue;
printf("%s\n", ent->d_name);
}
if (errno != 0)
perror("readdir");
closedir(dir);
return 0;
}
opendir() 是否成功. 和 ..如果你能贴出:
我可以更精确地告诉你为什么“返回空”。