递归降序遍历层次目录

来源:互联网 发布:程序员 产品设计 编辑:程序博客网 时间:2024/05/05 15:15
关于path_alloc函数::::
http://www.cnblogs.com/xiaoliyu/archive/2009/03/08/1406448.html
 
#include <sys/stat.h>#include <dirent.h>#include <limits.h>#include <stdio.h>#include <stdlib.h>#include <string.h>/* function type that is called for each filename */typedefintMyfunc(const char *, const struct stat *, int);static Myfuncmyfunc;static intmyftw(char *, Myfunc *);static intdopath(Myfunc *);static longnreg, ndir, nblk, nchr, nfifo, nslink, nsock, ntot;char*path_alloc(int* size){char *p = NULL;if(!size) return NULL;p = malloc(256);if(p)*size = 256;else*size = 0;return p;}intmain(int argc, char *argv[]){intret;if (argc != 2)printf("usage:  ftw  <starting-pathname>");ret = myftw(argv[1], myfunc);/* does it all */ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock;if (ntot == 0)ntot = 1;/* avoid divide by 0; print 0 for all counts */printf("regular files  = %7ld, %5.2f %%\n", nreg,  nreg*100.0/ntot);printf("directories    = %7ld, %5.2f %%\n", ndir,  ndir*100.0/ntot);printf("block special  = %7ld, %5.2f %%\n", nblk,  nblk*100.0/ntot);printf("char special   = %7ld, %5.2f %%\n", nchr,  nchr*100.0/ntot);printf("FIFOs          = %7ld, %5.2f %%\n", nfifo,  nfifo*100.0/ntot);printf("symbolic links = %7ld, %5.2f %%\n", nslink,  nslink*100.0/ntot);printf("sockets        = %7ld, %5.2f %%\n", nsock,  nsock*100.0/ntot);exit(ret);}/* * Descend through the hierarchy, starting at "pathname". * The caller's func() is called for every file. */#defineFTW_F1/* file other than directory */#defineFTW_D2/* directory */#defineFTW_DNR3/* directory that can't be read */#defineFTW_NS4/* file that we can't stat */static char*fullpath;/* contains full pathname for every file */static int/* we return whatever func() returns */myftw(char *pathname, Myfunc *func){int len;fullpath = path_alloc(&len);/* malloc's for PATH_MAX+1 bytes *//* ({Prog pathalloc}) */strncpy(fullpath, pathname, len);/* protect against */fullpath[len-1] = 0;/* buffer overrun */return(dopath(func));}/* * Descend through the hierarchy, starting at "fullpath". * If "fullpath" is anything other than a directory, we lstat() it, * call func(), and return.  For a directory, we call ourself * recursively for each name in the directory. */static int/* we return whatever func() returns */dopath(Myfunc* func){struct statstatbuf;struct dirent*dirp;DIR*dp;intret;char*ptr;if (lstat(fullpath, &statbuf) < 0)/* stat error */return(func(fullpath, &statbuf, FTW_NS));if (S_ISDIR(statbuf.st_mode) == 0)/* not a directory */return(func(fullpath, &statbuf, FTW_F));/* * It's a directory.  First call func() for the directory, * then process each filename in the directory. */if ((ret = func(fullpath, &statbuf, FTW_D)) != 0)return(ret);ptr = fullpath + strlen(fullpath);/* point to end of fullpath */*ptr++ = '/';*ptr = 0;if ((dp = opendir(fullpath)) == NULL)/* can't read directory */return(func(fullpath, &statbuf, FTW_DNR));while ((dirp = readdir(dp)) != NULL) {if (strcmp(dirp->d_name, ".") == 0  ||    strcmp(dirp->d_name, "..") == 0)continue;/* ignore dot and dot-dot */strcpy(ptr, dirp->d_name);/* append name after slash */if ((ret = dopath(func)) != 0)/* recursive */break;/* time to leave */}ptr[-1] = 0;/* erase everything from slash onwards */if (closedir(dp) < 0)printf("can't close directory %s", fullpath);return(ret);}static intmyfunc(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", pathname);/* directories should have type = FTW_D */}break;case FTW_D:ndir++;break;case FTW_DNR:printf("can't read directory %s", pathname);break;case FTW_NS:printf("stat error for %s", pathname);break;default:printf("unknown type %d for pathname %s", type, pathname);}return(0);}

 

 

原创粉丝点击