目录遍历函数
DIR *opendir(const char *name);
struct dirent *readdir(DIR *dirp);
int closedir(DIR *dirp);
// 打开一个目录
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
参数:
- name: 需要打开的目录的名称
返回值:
DIR * 类型,理解为目录流
错误返回NULL
// 读取目录中的数据
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
- 参数:dirp是opendir返回的结果
- 返回值:
struct dirent,代表读取到的文件的信息
读取到了末尾或者失败了,返回NULL
// 关闭目录
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);
DIR *opendir(const char *name);
通过 readdir
函数移动。
struct dirent *readdir(DIR *dirp);
参数就是调用 opendir
返回的参数。
dirent是个结构体:
struct dirent
{
// 此目录进入点的inode
ino_t d_ino;
// 目录文件开头至此目录进入点的位移
off_t d_off;
// d_name 的长度, 不包含NULL字符
unsigned short int d_reclen;
// d_name 所指的文件类型
unsigned char d_type;
// 文件名
char d_name[256];
};
d_type (宏值)
DT_BLK - 块设备
DT_CHR - 字符设备
DT_DIR - 目录
DT_LNK - 软连接
DT_FIFO - 管道
DT_REG - 普通文件
DT_SOCK - 套接字
DT_UNKNOWN - 未知
测试:
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int getFileNum(const char * path);
// 读取某个目录下所有的普通文件的个数
int main(int argc, char * argv[]) {
if(argc < 2) {
printf("%s path\n", argv[0]);
return -1;
}
int num = getFileNum(argv[1]); // argv[1] 是文件路径 argv[0] 是命令
printf("普通文件的个数为:%d\n", num);
return 0;
}
// 用于获取目录下所有普通文件的个数
int getFileNum(const char * path) {
// 1.打开目录
DIR * dir = opendir(path);
if(dir == NULL) {
perror("opendir");
exit(0);
}
struct dirent *ptr; //创建dirent的结构体
// 记录普通文件的个数
int total = 0;
while((ptr = readdir(dir)) != NULL) { //读取到了末尾或者失败了,返回NULL
// 获取名称
char * dname = ptr->d_name;
// 忽略掉. 和.. ls -l获取目录,会发现可能有这种目录
if(strcmp(dname, ".") == 0 || strcmp(dname, "..") == 0) { // strcmp比较字符串,相同就等于0
continue;
}
// 判断是否是普通文件还是目录
if(ptr->d_type == DT_DIR) {
// 目录,需要继续读取这个目录
char newpath[256]; //定义新的数组用于存放 拼接后的路径,比如原来在Linux目录,里面有个lesson01,此时需要拼接
sprintf(newpath, "%s/%s", path, dname);
total += getFileNum(newpath); //递归
}
if(ptr->d_type == DT_REG) {
// 普通文件
total++; //只需统计一下个数
}
}
// 关闭目录
closedir(dir);
return total;
}
gcc readFileNum.c -o rFN
petri@XX:~/lesson01/05_io$ ./rFN /home/petri/lesson01/05_io
普通文件的个数为:38