温馨提示×

ubuntu copendir怎样配合readdir

小樊
45
2026-09-23 23:01:09
栏目: 智能运维

在 Ubuntu(Linux)下,opendir 和 readdir 是 POSIX 标准 API,通常配合在一起用来遍历目录。下面从用法、示例到注意事项给你一个完整说明。


一、基本关系

  • opendir():打开目录,返回一个 DIR *
  • readdir():读取目录项,每次返回一个 struct dirent *
  • closedir():关闭目录

流程一般是:

opendir -> readdir (循环) -> closedir

二、函数原型

#include <dirent.h>

DIR *opendir(const char *name);
struct dirent *readdir(DIR *dirp);
int closedir(DIR *dirp);

struct dirent 关键字段:

struct dirent {
    ino_t          d_ino;
    off_t          d_off;
    unsigned short d_rendtl;
    unsigned char  d_type;   // 文件类型
    char           d_name[256]; // 文件名
};

三、最小可用示例

1️⃣ 列出目录中所有文件名

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

int main(int argc, char *argv[]) {
    const char *path = argc > 1 ? argv[1] : ".";
    DIR *dir = opendir(path);
    if (!dir) {
        perror("opendir");
        return 1;
    }

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

    closedir(dir);
    return 0;
}

编译运行:

gcc listdir.c -o listdir
./listdir /tmp

四、过滤 . 和 ..

while ((entry = readdir(dir)) != NULL) {
    if (strcmp(entry->d_name, ".") == 0 ||
        strcmp(entry->d_name, "..") == 0)
        continue;

    printf("%s\n", entry->d_name);
}

五、判断文件类型(推荐用 stat)

方法 1:只用 d_type(不一定可靠)

if (entry->d_type == DT_DIR) {
    printf("[DIR] %s\n", entry->d_name);
}

⚠️ 某些文件系统(如某些网络文件系统)d_type 可能是 DT_UNKNOWN


方法 2:使用 stat(最可靠)

#include <sys/stat.h>

struct stat st;
char fullpath[512];
snprintf(fullpath, sizeof(fullpath), "%s/%s", path, entry->d_name);

if (stat(fullpath, &st) == 0) {
    if (S_ISDIR(st.st_mode))
        printf("[DIR] %s\n", entry->d_name);
    else
        printf("[FILE] %s\n", entry->d_name);
}

六、递归遍历目录(常见用法)

void list_dir(const char *path) {
    DIR *dir = opendir(path);
    if (!dir) return;

    struct dirent *entry;
    while ((entry = readdir(dir)) != NULL) {
        if (!strcmp(entry->d_name, ".") ||
            !strcmp(entry->d_name, ".."))
            continue;

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

        struct stat st;
        if (stat(fullpath, &st) == 0 && S_ISDIR(st.st_mode)) {
            printf("DIR: %s\n", fullpath);
            list_dir(fullpath);
        } else {
            printf("FILE: %s\n", fullpath);
        }
    }
    closedir(dir);
}

七、常见错误

❌ 忘记 closedir → 文件描述符泄漏
❌ 用 readdir 返回指针后长期保存(struct dirent 会被覆盖)
❌ 用 readdir 做线程安全操作(它不是线程安全的)

✅ 多线程请用 readdir_r(已废弃但可用)或 readdir64_r


八、总结一句话

opendir 打开目录,readdir 一个个读,closedir 收尾,stat 判断类型

如果你有具体需求(比如:按后缀过滤、统计文件数、递归删除),可以直接说,我可以给你对应代码。

0 踩