首页 > 代码库 > 递归降序遍历目录层次结构

递归降序遍历目录层次结构

在学习APUE第4章时候,里面编写了一段递归顺序遍历目录层次的结构的代码,该代码实现了递归访问目录。但是该代码并没有显示降序的方式显示目录树。

因此,我讲代码稍微修改,使其能够按照tree命令的方式显示,同时也统计了各个文件的数量。

#include<iostream>
#include<cstring>
#include<vector>
#include<dirent.h>
#include<unistd.h>
#include<algorithm>
#include<fstream>
#include<sys/stat.h>
using namespace std;

#define  FTW_F   1   // file other than directory
#define  FTW_D   2   //the directory
#define  FTN_DNR 3   //the directory that we can not access
#define  FTW_NS  4   //file that can not stat
};
ofstream fcout("a.txt");
void myftw(char *ss,int level);
long myfunc(const char *pathname);
int main(int argc,char* argv[])
{
         if(argc!=2)
                  cout<<"usage: ftw [pathname]"<<endl;
         myftw(argv[1],0);
         cout<<"FIFOS="<<myfileInfo.npipe<<","<<myfileInfo.npipe*100.0/total<<"%"<<endl;
         return 0;
}
 char *pathname=new char(PATHMAX);
 struct compare
 {
        bool operator() (char *str1,char *str2)
        {
                return strcmp(str1,str2)<0;
        }
 };

 void myftw(char *filepath,int level)
 {

          DIR *dp;
          struct dirent *dirp;
          //char *pathname=new char(PATHMAX);
          char *path;
          vector<char *> vec;
          vector<char *>::iterator iter;
          strcpy(pathname,filepath);
          int len=strlen(filepath);
          path=pathname+len;
          *path++=‘/‘;
          *path=0;
          cout<<"pathname:"<<pathname<<endl;
          if((dp=opendir(pathname))==NULL)
                 cout<<"open dir error!"<<endl;
          while((dirp=readdir(dp))!=NULL)
          {
                  if(strcmp(dirp->d_name,".")==0||strcmp(dirp->d_name,"..")==0)
                        continue;
                 vec.push_back(dirp->d_name);
          }
          //sort the file ,在显示结果的时候使其保证是升序显示,使用compare结构体,
	  //而不直接使用strcmp是因为,strcmp返回的不是bool类型。
          sort(vec.begin(),vec.end(),compare());
          for(iter=vec.begin();iter!=vec.end();iter++)
          {
                char *p=*iter;
                strcpy(path,p);
                if(myfunc(pathname)!=S_IFDIR)
                {
                        for(int i=0;i<level;i++)
                                fcout<<black;
                        fcout<<begin<<*iter<<endl;
                }
                else
                        myftw(pathname,level+1);
                *path=0;
          }
  }

  long myfunc(const char *pathname)
  {
          struct stat statbuf;
          if(lstat(pathname,&statbuf)<0)
                  cout<<"the file can not stat!"<<endl;
          if(S_ISREG(statbuf.st_mode))
          {
                myfileInfo.nreg++;
                return S_IFREG;
          }
          else if(S_ISDIR(statbuf.st_mode))
          {
                 myfileInfo.ndir++;
                return S_IFDIR;
          }
          else if(S_ISCHR(statbuf.st_mode))
          {
                myfileInfo.nchar++;
                return  S_IFCHR;
          }
          else if(S_ISBLK(statbuf.st_mode))
          {
                myfileInfo.nblock++;
                return S_IFBLK;
          }
          else if(S_ISFIFO(statbuf.st_mode))
          {
                myfileInfo.npipe++;
                return S_IFIFO;
          }
          else if(S_ISLNK(statbuf.st_mode))
          {
                myfileInfo.nlink++;
                return S_IFLNK;
          }
          else if(S_ISSOCK(statbuf.st_mode))
          {
                myfileInfo.nsock++;
                return S_IFSOCK;
          }
          else
          {
                cout<<"no type"<<endl;
                return -1;
          }
}
                                                                   
该代码与书上代码相比,有一点不足,就是没有将出错的信息非常全面的显示出来。