Linux中统计文件夹内各种文件类型的数量

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <dirent.h> #include <sys/stat.h> #include <string.h> enum {FTW_F=1,FTW_D,FTW_DNR,FTW_NS}; static long nreg,ndir,nblk,nchr,nfifo,nslink,nsock; typedef int (*Myfunc)(const char*,const struct stat*,int); static int accumulate(const char*,const struct stat*,int); static int walk(Myfunc); static int start(const char*,Myfunc); int main(int argc,char** argv) { if(argc!=2) { printf("Usage:traverser director"); exit(-1); } start(argv[1],accumulate); printf("nreg %d/nndir %d/nnblk %d/nnchr %d/nnfifo %d/nnslink %d/nnsock %d/n",nreg,ndir,nblk,nchr,nfifo,nslink,nsock); } static char* fullpath; static int start(const char* pathname,Myfunc func) { int len; len=256; fullpath=malloc(len); strcpy(fullpath,pathname); return walk(func); } static int walk(Myfunc func) { struct stat statbuf; DIR* dp; struct dirent* entry; char* ptr; int ret; if(lstat(fullpath,&statbuf)<0) { return func(fullpath,&statbuf,FTW_NS); } if(S_ISDIR(statbuf.st_mode)==0) { return func(fullpath,&statbuf,FTW_F); } if((ret=func(fullpath,&statbuf,FTW_D))!=0) { return ret; } ptr=fullpath+strlen(fullpath); *ptr++='/'; *ptr=0; if(!(dp=opendir(fullpath))) { return func(fullpath,&statbuf,FTW_DNR); } while(entry=readdir(dp)) { if( strcmp(entry->d_name,".")==0 || strcmp(entry->d_name,"..")==0) { continue; } strcpy(ptr,entry->d_name); if((ret=walk(func))!=0) { break; } } *--ptr=0; closedir(dp); return ret; } static int accumulate(const char* pathname,const struct stat* statptr,int type) { switch(type) { case FTW_F: switch(statptr->st_mode & S_IFMT) { case S_IFREG: nreg++; break; case S_IFBLK: nblk++; break; case S_IFCHR: nchr++; break; case S_IFIFO: nfifo++; break; case S_IFLNK: nslink++; break; case S_IFSOCK: nsock++; break; case S_IFDIR: printf("for S_IFDIR for %s/n",pathname); exit(-1); } break; case FTW_D: ndir++; break; case FTW_DNR: printf("Can't read directory %s/n",pathname); return -1; case FTW_NS: printf("stat error for %s/n",pathname); return -1; } return 0; }  

这段代码用来统计文件夹中各种文件的数量。

通过这个练习,熟悉了文件类型的判断。

 

这段代码中有些很巧妙的技巧:

1.递归时,同一个函数的循环中,为了消除平凡的字符串加减,用另外一根指针指向会改变的部分,然后每次将新的文件名,从这里开始增加,直接覆盖前一个名字。

2.一次递归结束,进行回溯时,用ptr[-1]=0来去掉slash后面的文件名。如/etc/httpd,ptr指向h。

你可能感兴趣的:(linux,struct,include)