您的位置:首页 > 运维架构 > Linux

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

2009-12-05 23:47 441 查看
#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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: