温馨提示×

ubuntu readdir为什么返回空

小樊
50
2026-09-18 18:29:59
栏目: 智能运维

在 Ubuntu(Linux)下调用 readdir 返回“空”,通常不是真的返回了 NULL 而没有错误,而是对返回值的理解或目录状态有问题。下面按常见原因逐个说明。


一、readdir 到底什么时候“返回空”

struct dirent *readdir(DIR *dirp);
  • 返回非 NULL:读到一个目录项
  • 返回 NULL
    • 目录读取结束(正常)
    • 或发生错误(此时 errno 被设置)

⚠️ 注意:
readdir 不会返回“空字符串文件名”来表示空目录,空目录至少会有:

.
..

二、最常见原因

1️⃣ 目录本身确实是空的(但至少有 ...

如果你看到:

while ((entry = readdir(dir)) != NULL) {
    // 什么都没打印
}

但目录真的是空的,那说明:

  • 目录里没有用户文件
  • 循环直接结束(NULL)

✅ 正常现象


2️⃣ 目录路径错误 / 打开失败

DIR *dir = opendir("/some/path");
if (!dir) {
    perror("opendir");
    return;
}

如果:

  • 路径不存在
  • 权限不足

opendir 会返回 NULL,但你却仍然调用了 readdir,这是未定义行为,可能表现为“一直返回 NULL”。

✅ 检查:

ls -ld /some/path

3️⃣ 你读的是文件而不是目录

opendir("test.txt");

如果 test.txt 是普通文件:

  • opendir 返回 NULL
  • 或某些情况下行为异常

✅ 用 stat 检查:

struct stat st;
stat(path, &st);
if (!S_ISDIR(st.st_mode)) {
    printf("不是目录\n");
}

4️⃣ 权限不足(非常常见)

即使 opendir 成功:

  • 没有 执行权限(x) 的目录
  • 或父目录无权限

会导致:

  • readdir 返回 NULL
  • errno == EACCES

✅ 检查:

ls -l 目录父路径

5️⃣ 你只看 d_name 但没打印

错误示例:

while ((entry = readdir(dir)) != NULL) {
    // 忘了 printf
}

或:

if (entry->d_name == "")  // 错误判断

✅ 正确用法:

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

6️⃣ 网络连接目录 / 挂载点未挂载

例如:

  • NFS
  • SMB
  • /mnt/xxx 未真正挂载

表现:

  • opendir 成功
  • readdir 立即返回 NULL
  • errno == ENOENTENOTCONN

7️⃣ 目录被并发修改

如果:

  • 另一个进程在删文件
  • 或目录正在被卸载

可能导致:

  • readdir 提前返回 NULL
  • errno != 0

三、推荐的健壮写法

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

DIR *dir = opendir(path);
if (!dir) {
    perror("opendir");
    return;
}

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

if (errno != 0) {
    perror("readdir");
}

closedir(dir);

四、快速排查清单

✅ 目录存在吗?
✅ 是目录吗?
✅ 有读+执行权限吗?
opendir 成功了吗?
readdir 返回 NULL 时 errno 是多少?
✅ 目录里真的有文件吗?


如果你愿意,可以把:

  • 你的 readdir 代码片段
  • ls -l 目录
  • errno

发出来,我可以直接帮你定位是哪一条原因。

0