本节主要讲述了对unix系统对读目录的讲述。首先了解一下了解一下下面的函数
#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 * readdir (DIR *dirstream) [Function]
This function reads the next entry from the directory. It normally returns a pointer to
a structure containing information about the file. This structure is statically allocated
and can be rewritten by a subsequent call.
Portability Note: On some systems readdir may not return entries for ‘.’ and ‘..’,
even though these are always valid file names in any directory. See Section 11.2.2
[File Name Resolution], page 224.
If there are no more entries in the directory or an error is detected, readdir returns
a null pointer. The following errno error conditions are defined for this function:
EBADF The dirstream argument is not valid.
readdir is not thread safe. Multiple threads using readdir on the same dirstream
may overwrite the return value. Use readdir_r when this is critical.
int closedir (DIR *dirstream) [Function]
This function closes the directory stream dirstream. It returns 0 on success and -1
on failure.
The following errno error conditions are defined for this function:
EBADF The dirstream argument is not valid.
其他的就不写了,本章主要是通过运用以上函数来实现遍历目录层次结构,并按文件类型进行技术。
直接上代码:
#include "apue.h" #include <dirent.h> #include<limits.h> typedef int Myfunc(const char* ,const struct stat* ,int); static Myfunc myfunc; static int myftw(char* ,Myfunc*); static int dopath(Myfunc *); static long nreg,ndir,nblk,nchr,nfifo,nslink,nsock,ntot; int main(int argc,char** argv) { int ret; if(argc!=2) err_quit("usage:ftw<starting-pathname>"); ret=myftw(argv[1],myfunc); ntot=nreg+ndir+nblk+nchr+nfifo+nslink+nsock; if(ntot==0) ntot=1; printf("regular files= %7ld,%5.2f %%\n",nreg,nreg*100.0/ntot); printf("regular files= %7ld,%5.2f %%\n",ndir,ndir*100.0/ntot); printf("regular files= %7ld,%5.2f %%\n",nblk,nblk*100.0/ntot); printf("regular files= %7ld,%5.2f %%\n",nchr,nchr*100.0/ntot); printf("regular files= %7ld,%5.2f %%\n",nfifo,nfifo*100.0/ntot); printf("regular files= %7ld,%5.2f %%\n",nslink,nslink*100.0/ntot); printf("regular files= %7ld,%5.2f %%\n",nsock,nsock*100.0/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; } #define FTW_F 1 #define FTW_D 2 #define FTW_DNR 3 #define FTW_NS 4 static char *fullpath; static int myftw(char* pathname,Myfunc* func) { int len; fullpath=path_alloc(&len); strncpy(fullpath,pathname,len); fullpath[len-1]=0; return (dopath(func)); } static int dopath(Myfunc* func) { struct stat statbuf; struct dirent *dirp; DIR* dp; int ret; char *ptr; 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))==NULL) return(func(fullpath,&statbuf,FTW_DNR)); while((dirp=readdir(dp))!=NULL){ if(strcmp(dirp->d_name,".")==0|| strcmp(dirp->d_name,"..")==0) continue; strcpy(ptr,dirp->d_name); if((ret=dopath(func))!=0) break; } ptr[-1]=0; if(closedir(dp)<0) err_ret("can't clost dir %s",fullpath); return(ret); } static int myfunc(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: err_dump("for S_IFDIR for %s",pathname); } break; case FTW_D: ndir++; break; case FTW_DNR: err_ret("can't read directory %s",pathname); break; case FTW_NS: err_ret("stat error for %s",pathname); break; default: err_dump("unkown type %d for pathname %s",type,pathname); } return(0); }
这个经过修正可以正常运行了
运行结果