温馨提示×

ubuntu copendir怎么实现

小樊
39
2026-07-07 15:29:23
栏目: 智能运维

Ubuntu(Linux) 下,opendir() 是用来打开一个目录流的函数,常用于遍历目录。它是 POSIX 标准 API,在 <dirent.h> 中定义。

下面从 原理 + 示例 + 常见用法 给你讲清楚。


一、opendir 是什么?

#include <dirent.h>

DIR *opendir(const char *name);

作用

打开一个目录,返回一个 DIR* 目录流指针,供后续 readdir()closedir() 使用。

返回值

  • 成功:返回 DIR*
  • 失败:返回 NULL,并设置 errno

二、基本使用示例(最常用)

示例:列出目录下的所有文件名

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

int main(int argc, char *argv[])
{
    const char *path = ".";  // 当前目录
    DIR *dir = opendir(path);

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

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

    closedir(dir);
    return 0;
}

编译运行

gcc opendir_test.c -o opendir_test
./opendir_test

三、关键数据结构说明

1️⃣ DIR

DIR *dir;

目录流指针(类似 FILE*


2️⃣ struct dirent

struct dirent {
    ino_t          d_ino;       // inode 号
    off_t          d_off;
    unsigned short d_reclen;
    unsigned char  d_type;      // 文件类型(DT_REG / DT_DIR)
    char           d_name[256]; // 文件名
};

常用字段

  • d_name:文件名
  • d_type:文件类型(不是所有文件系统都支持)

四、过滤 ...

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

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

五、判断文件类型(推荐方式)

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

if (entry->d_type == DT_REG)
    printf("普通文件: %s\n", entry->d_name);
else if (entry->d_type == DT_DIR)
    printf("目录: %s\n", entry->d_name);

⚠️ 某些文件系统(如 XFS、NFS)可能返回 DT_UNKNOWN


方法 2:lstat()(最可靠 ✅)

#include <sys/stat.h>
#include <string.h>

struct stat st;
char fullpath[512];

snprintf(fullpath, sizeof(fullpath), "%s/%s", path, entry->d_name);
lstat(fullpath, &st);

if (S_ISREG(st.st_mode))
    printf("文件: %s\n", entry->d_name);
else if (S_ISDIR(st.st_mode))
    printf("目录: %s\n", entry->d_name);

六、opendir / readdir / closedir 关系

opendir()   → 打开目录
readdir()   → 读取目录项
closedir()  → 关闭目录

七、常见错误

1️⃣ 忘记 closedir

// ❌ 会导致文件描述符泄露

2️⃣ 用错头文件

#include <dirent.h>  // 必须

3️⃣ 用 fopen 打开目录

// ❌ 目录不能用 fopen

八、替代方案(高级)

方法 说明
nftw() 递归遍历目录
scandir() 可排序、可过滤
readdir_r() 已废弃(不推荐)

九、总结一句话

在 Ubuntu 下,opendir() + readdir() + closedir() 是遍历目录的标准做法。

如果你需要:

  • 递归遍历目录
  • 实现 ls 命令
  • 文件搜索工具
  • C++ 实现

可以直接告诉我,我可以给你完整代码。

0