温馨提示×

ubuntu copendir要注意啥

小樊
45
2026-10-02 17:00:04
栏目: 智能运维

在 Ubuntu(Linux)下使用 opendir() 函数时,有几个常见的注意点和坑,下面按使用流程 + 易错点说明:


一、基本用法回顾

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

DIR *dir = opendir("/path/to/dir");
if (dir == NULL) {
    perror("opendir");
    return -1;
}

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

closedir(dir);

二、需要注意的关键点

1️⃣ 头文件不能少

#include <dirent.h>
#include <sys/types.h>   // 通常 dirent.h 已包含,但写上更稳妥

否则可能报:

implicit declaration of function 'opendir'

2️⃣ 返回值必须判空

if (dir == NULL) {
    perror("opendir");
}

常见失败原因:

  • 路径不存在
  • 权限不足
  • 不是目录(是普通文件)

3️⃣ 路径必须是「目录」,不能是文件

opendir("test.txt"); // ❌ 错误

如果是文件,opendir 返回 NULL,errno = ENOTDIR


4️⃣ readdir 返回的 . 和 .. 要处理

if (strcmp(entry->d_name, ".") == 0 ||
    strcmp(entry->d_name, "..") == 0)
    continue;

否则会:

  • 死循环(递归时)
  • 输出无意义内容

5️⃣ opendir 和 closedir 必须配对

opendir → readdir → closedir

忘记 closedir() 会:

  • 文件描述符泄漏
  • 长时间运行程序可能炸

6️⃣ 线程安全问题(重要)

  • readdir() 不是线程安全
  • 多线程请用:
readdir_r(dir, entry, &result);

或使用 readdir + 加锁


7️⃣ entry->d_type 不是所有文件系统都支持

if (entry->d_type == DT_REG) { ... }

注意:

  • 某些文件系统(如部分 NFS)d_type == DT_UNKNOWN
  • 不能 100% 依赖
  • 准确判断类型要用 stat()

8️⃣ 路径拼接要用 snprintf

char path[PATH_MAX];
snprintf(path, sizeof(path), "%s/%s", dir_path, entry->d_name);

避免:

  • 缓冲区溢出
  • 路径拼接错误

9️⃣ Ubuntu 下编译

gcc dir.c -o dir

不需要额外链接库(libc 默认)


三、常见错误汇总

问题 原因
Segmentation fault 未判 opendir == NULL
死循环 没跳过 . / ..
打开失败 权限不够 / SELinux / 路径错
递归爆栈 深度过大或未过滤符号链接

四、进阶建议

  • 递归遍历目录:注意符号链接(S_ISLNK)
  • 大目录:考虑 getdents()(底层)
  • C++:直接用 std::filesystem(C++17)

如果你愿意,可以告诉我:

  • 你是 C / C++?
  • 是否 递归遍历?
  • 是否在 多线程 环境?

我可以给你一份可直接用的完整示例。

0 踩