递归降序遍历目录层次结构,并按文件类型计数。
先介绍相关的函数:
#include<dirent.h> DIR *opendir(const char *pathname); //打开目录 返回值:成功返回指针,出错返回NULL struct dirent *readdir(DIR *dp); //读取目录 返回值:成功返回指针,出错返回NULL void rewinddir(DIR *dp); //重设读取目录的位置为开头位置 int closedir(DIR *dp); //关闭目录 返回值:成功返回0,出错返回-1 long telldir(DIR *dp); //取得目录流的读取位置 返回值:与dp关联的目录中的当前位置 void seekdir(DIR *dp, long loc); //设置下回读取目录的位置 struct dirent{ ino_t d_ino; //i-node number char d_name[NAME_MAX + 1]; //null-terminated filename }
改写APUE的代码:
1 #include<stdio.h> 2 #include<dirent.h> 3 #include<sys/stat.h> 4 #include<string.h> 5 #include<stdlib.h> 6 7 static int nreg = 0, ndir = 0, nblk = 0, nchr = 0, nfifo = 0, nslink = 0, nsock = 0, ntot = 0; 8 9 static char *fullpath; 10 11 int myfunc(const char *pathname, const struct stat *statptr, int type) 12 { 13 switch(type){ 14 case 1: 15 switch(statptr->st_mode & S_IFMT){ 16 case S_IFREG: nreg++; break; 17 case S_IFBLK: nblk++; break; 18 case S_IFCHR: nchr++; break; 19 case S_IFIFO: nfifo++; break; 20 case S_IFLNK: nslink++; break; 21 case S_IFSOCK: nsock++; break; 22 case S_IFDIR:{ 23 printf("for S_IFDIR for %s ",pathname); 24 } 25 } 26 break; 27 case 2: //文件夹 28 ndir++; break; 29 case 3: 30 printf("cant read directory %s ",pathname); 31 case 4: 32 printf("stat error for %s ",pathname); 33 } 34 35 return 0; 36 } 37 38 int dopath() 39 { 40 struct stat statbuf; //文件信息 41 struct dirent *dirp; //文件夹信息,包括i-node number filename 42 DIR *dp; //打开目录返回的指针 43 char *ptr; 44 45 if((lstat(fullpath,&statbuf)) < 0) 46 return(myfunc(fullpath,&statbuf,4)); 47 if(S_ISDIR(statbuf.st_mode) == 0) //判断是否是文件夹 48 return(myfunc(fullpath,&statbuf,1)); 49 50 myfunc(fullpath,&statbuf,2); //是目录则调用函数使目录数量自加一 51 52 ptr = fullpath + strlen(fullpath); 53 *ptr++ = '/'; 54 *ptr = 0; 55 56 if((dp = opendir(fullpath)) == NULL) 57 return(myfunc(fullpath,&statbuf,3)); 58 59 while((dirp = readdir(dp)) != NULL){ 60 if(strcmp(dirp->d_name,".") == 0 || strcmp(dirp->d_name,"..") == 0) 61 continue; 62 strcpy(ptr, dirp->d_name); 63 64 dopath(); 65 } 66 67 closedir(dp); 68 69 } 70 71 void ftw(char *pathname) 72 { 73 #ifdef PATH_MAX 74 const int PATH_LEN = PATH_MAX; 75 #else 76 const int PATH_LEN = 1024; 77 #endif 78 79 fullpath = malloc(PATH_LEN); 80 81 strncpy(fullpath,pathname,PATH_LEN); 82 83 fullpath[PATH_LEN - 1] = '