使用 C 语言中的 opendir 函数
Jinku Hu
2023年10月12日
本文将介绍几种在 C 语言中使用 opendir
函数的方法。
使用 opendir
函数打开一个目录流
opendir
函数是 POSIX 规范的一部分,在 <dirent.h>
头文件中定义。该函数使用一个 char
指针参数来指定要打开的目录名。opendir
返回 DIR*
结构,如果遇到错误则返回 NULL。DIR
数据类型是为了表示目录流而实现的,但用户不应该分配 DIR
类型的对象。在下面的示例代码中,我们从第一个命令行参数中获取目录名,并将其值传递给 opendir
函数。
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.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
循环,打印打开的目录流中的每个条目。我们修改了 opendir
和 closedir
函数调用周围的代码,以检查错误并输出相应的信息进行调试。检查库函数是否成功返回总是好的、安全的做法。
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.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 <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.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);
}
作者: Jinku Hu