在學習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;
}
}
該代碼與書上代碼相比,有一點不足,就是沒有將出錯的信息非常全面的顯示出來。