使用 C 语言中的 opendir 函数

Jinku Hu 2023年1月30日 2021年2月28日
  1. 使用 opendir 函数打开一个目录流
  2. 使用 readdir 函数来遍历目录条目
使用 C 语言中的 opendir 函数

本文将介绍几种在 C 语言中使用 opendir 函数的方法。

使用 opendir 函数打开一个目录流

opendir 函数是 POSIX 规范的一部分,在 <dirent.h> 头文件中定义。该函数使用一个 char 指针参数来指定要打开的目录名。opendir 返回 DIR*结构,如果遇到错误则返回 NULL。DIR 数据类型是为了表示目录流而实现的,但用户不应该分配 DIR 类型的对象。在下面的示例代码中,我们从第一个命令行参数中获取目录名,并将其值传递给 opendir 函数。

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

int main(int argc, char *argv[])
{
    DIR *dp;
    struct dirent *dirp;

    if (argc != 2) {
        fprintf(stderr, "Usage: ./program directory_name\n");
        exit(EXIT_FAILURE);
    }

    dp = opendir(argv[1]);

    while ((dirp = readdir(dp)) != NULL)
        printf("%s\n", dirp->d_name);

    closedir(dp);
    exit(EXIT_SUCCESS);
}

使用 readdir 函数来遍历目录条目

一旦目录流打开,我们检索到有效的 DIR*,我们就可以使用 readdir 函数读取其中的每个条目。每次调用 readdir 函数都会返回一个指向 dirent 结构的指针,代表下一个目录条目。当到达目录流的终点时,readdir 返回 NULL。因此,我们实现了一个简单的 while 循环,打印打开的目录流中的每个条目。我们修改了 opendirclosedir 函数调用周围的代码,以检查错误并输出相应的信息进行调试。检查库函数是否成功返回总是好的、安全的做法。

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

int main(int argc, char *argv[])
{
    DIR *dp;
    struct dirent *dirp;

    if (argc != 2) {
        fprintf(stderr, "Usage: ./program directory_name\n");
        exit(EXIT_FAILURE);
    }

    errno = 0;
    if ((dp = opendir(argv[1])) == NULL) {
        switch (errno) {
            case EACCES: printf("Permission denied\n"); break;
            case ENOENT: printf("Directory does not exist\n"); break;
            case ENOTDIR: printf("'%s' is not a directory\n", argv[1]); break;
        }
        exit(EXIT_FAILURE);
    }

    while ((dirp = readdir(dp)) != NULL)
        printf("%s\n", dirp->d_name);

    if (closedir(dp) == -1)
        perror("closedir");

    exit(EXIT_SUCCESS);
}

另外,我们还可以为 readdir 函数增加一些查错的条件语句,因为前面的例子可能会在目录名无效或发生其他错误时产生不清晰的输出。下面的代码会在遍历成功后额外输出目录结束的达成状态。

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

int main(int argc, char *argv[])
{
    DIR *dp;
    struct dirent *dirp;

    if (argc != 2) {
        fprintf(stderr, "Usage: ./program directory_name\n");
        exit(EXIT_FAILURE);
    }

    errno = 0;
    if ((dp = opendir(argv[1])) == NULL) {
        switch (errno) {
            case EACCES: printf("Permission denied\n"); break;
            case ENOENT: printf("Directory does not exist\n"); break;
            case ENOTDIR: printf("'%s' is not a directory\n", argv[1]); break;
        }
        exit(EXIT_FAILURE);
    }

    errno = 0;
    while ((dirp = readdir(dp)) != NULL)
        printf("%s\n", dirp->d_name);

    if (errno != 0) {
        if (errno == EBADF)
            printf("Invalid directory stream descriptor\n");
        else
            perror("readdir");
    } else {
        printf("End-of-directory reached\n");
    }

    if (closedir(dp) == -1)
        perror("closedir");

    exit(EXIT_SUCCESS);
}
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn

相关文章 - C File