首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【嵌入式Linux应用开发基础】opendir函数、readdir函数和closedir函数(一)

【嵌入式Linux应用开发基础】opendir函数、readdir函数和closedir函数(一)

作者头像
byte轻骑兵
发布2026-01-21 15:22:48
发布2026-01-21 15:22:48
810
举报

在嵌入式 Linux 应用开发中,opendirreaddirclosedir 函数是用于处理目录操作的重要函数,它们共同构成了遍历目录内容的基本工具。

一、opendir 函数

1.1 函数原型及头文件

代码语言:javascript
复制
#include <sys/types.h>
#include <dirent.h>

DIR *opendir(const char *name);

1.2 功能描述

opendir 函数用于打开一个指定名称的目录,并返回一个指向 DIR 类型对象的指针。DIR 类型是一个不透明的数据类型,用于表示一个打开的目录流,后续的 readdirclosedir 函数将使用这个目录流来进行操作。

1.3 参数说明

  • name:要打开的目录的路径名,可以是绝对路径或相对路径。

1.4 返回值

  • 成功时,返回一个指向 DIR 类型对象的指针,该指针可用于后续的目录读取操作。
  • 失败时,返回 NULL,并设置 errno 变量来指示具体的错误原因,常见的错误包括目录不存在、权限不足等。

1.5 示例代码

代码语言:javascript
复制
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>

int main() {
    DIR *dir;
    const char *dir_name = "/tmp";

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

    // 后续可以使用 dir 进行目录读取操作

    // 关闭目录
    closedir(dir);
    return 0;
}

二、readdir 函数

2.1 函数原型及头文件

代码语言:javascript
复制
#include <dirent.h>

struct dirent *readdir(DIR *dirp);

2.2 功能描述

readdir 函数用于从一个打开的目录流中读取下一个目录项,并返回一个指向 struct dirent 类型对象的指针。每次调用 readdir 函数,它都会返回目录中的下一个文件或子目录的信息,直到目录的末尾。

2.3 参数说明

  • dirp:指向 DIR 类型对象的指针,该指针是通过 opendir 函数返回的。

2.4 返回值

  • 成功时,返回一个指向 struct dirent 类型对象的指针,该对象包含了当前目录项的信息,如文件名、文件类型等。
  • 当到达目录末尾时,返回 NULL,并且不会设置 errno 变量。
  • 如果发生错误,返回 NULL,并设置 errno 变量来指示具体的错误原因。

2.5 struct dirent 结构体

struct dirent 结构体定义了目录项的信息,常见的成员如下:

代码语言:javascript
复制
struct dirent {
    ino_t          d_ino;       /* inode number */
    off_t          d_off;       /* not an offset; see NOTES */
    unsigned short d_reclen;    /* length of this record */
    unsigned char  d_type;      /* type of file; not supported by all filesystem types */
    char           d_name[256]; /* filename */
};
  • d_ino:文件的索引节点号。
  • d_type:文件的类型,常见的值包括 DT_REG(普通文件)、DT_DIR(目录)、DT_LNK(符号链接)等。
  • d_name:文件名。

2.6 示例代码

代码语言:javascript
复制
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>

int main() {
    DIR *dir;
    struct dirent *entry;
    const char *dir_name = "/tmp";

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

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

    closedir(dir);
    return 0;
}

三、closedir 函数

3.1 函数原型及头文件

代码语言:javascript
复制
#include <sys/types.h>
#include <dirent.h>

int closedir(DIR *dirp);

3.2 功能描述

closedir 函数用于关闭一个之前通过 opendir 函数打开的目录流,并释放相关的资源。

3.3 参数说明

  • dirp:指向 DIR 类型对象的指针,该指针是通过 opendir 函数返回的。

3.4 返回值

  • 成功时,返回 0。
  • 失败时,返回 -1,并设置 errno 变量来指示具体的错误原因。

3.5 示例代码

代码语言:javascript
复制
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>

int main() {
    DIR *dir;
    const char *dir_name = "/tmp";

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

    // 进行目录读取操作

    if (closedir(dir) == -1) {
        perror("closedir");
        return 1;
    }

    return 0;
}

四、典型应用场景

4.1. 文件系统遍历与监控

①查找特定文件或目录:在嵌入式系统中,有时需要查找特定名称或类型的文件或目录。可以使用 opendir 打开指定目录,readdir 遍历目录下的所有项,通过比较 struct dirent 结构体中的 d_named_type 成员来找到目标文件或目录。

示例代码

代码语言:javascript
复制
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>

int find_file(const char *dir_path, const char *file_name) {
    DIR *dir = opendir(dir_path);
    if (dir == NULL) {
        perror("opendir");
        return -1;
    }

    struct dirent *entry;
    while ((entry = readdir(dir)) != NULL) {
        if (strcmp(entry->d_name, file_name) == 0) {
            closedir(dir);
            return 0;
        }
    }

    closedir(dir);
    return -1;
}

int main() {
    const char *dir_path = "/tmp";
    const char *file_name = "test.txt";
    if (find_file(dir_path, file_name) == 0) {
        printf("File found!\n");
    } else {
        printf("File not found.\n");
    }
    return 0;
}

②监控目录变化:嵌入式系统可能需要实时监控某个目录下的文件变化,如文件的创建、删除或修改。可以定期使用 opendirreaddir 遍历目录,记录文件列表,然后与上一次的记录进行比较,从而检测到目录的变化。

4.2. 配置文件加载

加载多个配置文件:在嵌入式系统中,可能存在多个配置文件存放在同一个目录下。可以使用 opendir 打开配置文件所在的目录,readdir 遍历目录下的所有文件,筛选出配置文件(如以 .conf 结尾的文件),然后依次加载这些配置文件。

示例代码

代码语言:javascript
复制
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>

void load_config_files(const char *config_dir) {
    DIR *dir = opendir(config_dir);
    if (dir == NULL) {
        perror("opendir");
        return;
    }

    struct dirent *entry;
    while ((entry = readdir(dir)) != NULL) {
        if (strstr(entry->d_name, ".conf") != NULL) {
            char file_path[256];
            snprintf(file_path, sizeof(file_path), "%s/%s", config_dir, entry->d_name);
            // 加载配置文件的具体逻辑
            printf("Loading config file: %s\n", file_path);
        }
    }

    closedir(dir);
}

int main() {
    const char *config_dir = "/etc/myapp/config";
    load_config_files(config_dir);
    return 0;
}

4.3. 日志管理

清理过期日志文件:嵌入式系统通常会产生大量的日志文件,为了避免占用过多的存储空间,需要定期清理过期的日志文件。可以使用 opendir 打开日志文件所在的目录,readdir 遍历目录下的所有日志文件,根据文件的创建时间或修改时间判断文件是否过期,如果过期则删除该文件。

示例代码

代码语言:javascript
复制
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>

void clean_expired_logs(const char *log_dir, time_t expiration_time) {
    DIR *dir = opendir(log_dir);
    if (dir == NULL) {
        perror("opendir");
        return;
    }

    struct dirent *entry;
    while ((entry = readdir(dir)) != NULL) {
        char file_path[256];
        snprintf(file_path, sizeof(file_path), "%s/%s", log_dir, entry->d_name);

        struct stat file_stat;
        if (stat(file_path, &file_stat) == 0) {
            if (file_stat.st_mtime < expiration_time) {
                if (unlink(file_path) == 0) {
                    printf("Deleted expired log file: %s\n", file_path);
                } else {
                    perror("unlink");
                }
            }
        }
    }

    closedir(dir);
}

int main() {
    const char *log_dir = "/var/log/myapp";
    time_t expiration_time = time(NULL) - 3600 * 24 * 7; // 过期时间为一周前
    clean_expired_logs(log_dir, expiration_time);
    return 0;
}

4.4. 媒体文件管理

播放列表生成:在嵌入式多媒体系统中,需要生成播放列表来管理媒体文件。可以使用 opendir 打开媒体文件所在的目录,readdir 遍历目录下的所有媒体文件(如 .mp3.avi 等),将这些文件的路径添加到播放列表中。

示例代码

代码语言:javascript
复制
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>

void generate_playlist(const char *media_dir) {
    DIR *dir = opendir(media_dir);
    if (dir == NULL) {
        perror("opendir");
        return;
    }

    FILE *playlist_file = fopen("playlist.txt", "w");
    if (playlist_file == NULL) {
        perror("fopen");
        closedir(dir);
        return;
    }

    struct dirent *entry;
    while ((entry = readdir(dir)) != NULL) {
        if (strstr(entry->d_name, ".mp3") != NULL || strstr(entry->d_name, ".avi") != NULL) {
            char file_path[256];
            snprintf(file_path, sizeof(file_path), "%s/%s", media_dir, entry->d_name);
            fprintf(playlist_file, "%s\n", file_path);
        }
    }

    fclose(playlist_file);
    closedir(dir);
}

int main() {
    const char *media_dir = "/mnt/media";
    generate_playlist(media_dir);
    return 0;
}

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-01-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、opendir 函数
    • 1.1 函数原型及头文件
    • 1.2 功能描述
    • 1.3 参数说明
    • 1.4 返回值
    • 1.5 示例代码
  • 二、readdir 函数
    • 2.1 函数原型及头文件
    • 2.2 功能描述
    • 2.3 参数说明
    • 2.4 返回值
    • 2.5 struct dirent 结构体
    • 2.6 示例代码
  • 三、closedir 函数
    • 3.1 函数原型及头文件
    • 3.2 功能描述
    • 3.3 参数说明
    • 3.4 返回值
    • 3.5 示例代码
  • 四、典型应用场景
    • 4.1. 文件系统遍历与监控
    • 4.2. 配置文件加载
    • 4.3. 日志管理
    • 4.4. 媒体文件管理
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档