C语言实现文件类型统计程序,C语言实现文件类型统计函数

#include#include#include#include#include#include#include

#define FTW_F 1 //标记非目录文件

#define FTW_D 2 //标记目录文件

#define FTW_DNR 3 //标记不可读目录

#define FTW_NS 4 //标记不可获得stat的文件

static char *fullpath; //保存文件的全路径

static size_t pathlen; //保存文件的路径长度//定义处理文件的函数

typedef int Myfunc(const char *,const struct stat*,int);staticMyfunc myfunc;static int myftw(char *,Myfunc *);static int dopath(Myfunc *);char *path_alloc(size_t *size_t);/*nreg:普通文件的个数; ndir: 目录文件的数量; nblk:块特殊文件的数量

nchr:字符特殊文件的数量 nfifo:管道特殊文件的数量

nslink:符号连接特殊文件的数量; nsock:套接字文件数量; ntot:总文件数量*/

static longnreg,ndir,nblk,nchr,nfifo,nslink,nsock,ntot;int main( int argc, char *argv[])

{intret;if(argc != 2)

{

printf("falut command input !\n");

exit(1);

}//计算各类文件的个数

ret = myftw(argv[1],myfunc);

ntot= nreg + ndir + nblk + nchr + nfifo + nslink +nsock;//避免除以0

if(ntot == 0)

{

ntot= 1;

}

printf("regular files = %7ld,%5.2f %%\n",nreg,nreg*100.0 /ntot);

printf("direciotn files = %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("sockers = %7ld,%5.2f %%\n",nsock,nsock*100.0 /ntot);

}//处理pathname并保存在一个全局的字符数组中,调用dopath

static int myftw(char *pathname,Myfunc *func)

{//为保存路径的字符串数组分配空间

fullpath = path_alloc(&pathlen);//如果分配内存空间不够就重新分配

if(pathlen <=strlen(pathname))

{

pathlen= strlen(pathname) * 2;if((fullpath = realloc(fullpath,pathlen )) ==NULL);

printf("realloc failed\n");

}//将路径名参数保存到全路径中,fullpath是全局变量,dopath函数可以调用

strcpy(fullpath,pathname);return(dopath(func));

}//路径数组分配

char *path_alloc(size_t *size)

{char *p =NULL;if(!size)returnNULL;

p= malloc(256);if(p)*size = 256;else

*size = 0;returnp;

}//dopath用于判断是否是目录,然后根据选择情况是直接进入myfun函数取技术//还是递归调用dopath函数

static int dopath(Myfunc *func)

{structstat statbuf;struct dirent *dirp;

DIR*dp;intret,n;//调用lstat获取路径名的stat信息,如果不成功,调用func函数,并传递给FTW_NS

if(lstat(fullpath,&statbuf) < 0)return (func(fullpath, &statbuf, FTW_NS));//查看文件stat结构的st_mode,如果不是目录,调用func函数//并传递给FTW_F,交由myfun进一步判断文件类型

if(S_ISDIR(statbuf.st_mode) == 0)return(func(fullpath,&statbuf,FTW_F));//最后一种情况就是该路径名代表的是一个目录,此次的fun的正常情况返回0//所以执行完func后还不会返回,会继续执行func

if((ret = func(fullpath,&statbuf,FTW_D)) != 0)return(ret);//路径处理,扩充路径空间长度

n =strlen(fullpath);if(n + NAME_MAX + 2 >pathlen)

{

pathlen*= 2;if((fullpath = realloc(fullpath,pathlen)) ==NULL)

{

printf("realoc failed\n");

}

}

fullpath[n++] = '/';

fullpath[n]= 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(&fullpath[n],dirp->d_name); //在“/”之后加上当前目录项的命中

if((ret = dopath(func)) != 0) //然后采用新的路径名递递归的调用dopath

break;

}

fullpath[n-1] = 0;//关闭目录

if(closedir(dp) < 0)

printf("can't close directory %s",fullpath);returnret;

}//通过stat结构的st_mode字段来判断文件的类型,并计数

static int myfunc(const char *pathname,const struct stat *statptr,inttype)

{switch(type)

{//会与非目录情况进行处理

caseFTW_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;caseS_IFDIR:

printf("for S_IFDIR for %s",pathname);

}break;//对于目录文件进行处理

caseFTW_D:

ndir++;break;//对于不可读目录进行处理

caseFTW_DNR:

printf("%s dir isn't read",pathname);break;caseFTW_NS:

printf("%s stat error",pathname);default:

printf("%d type aren't identified, path is %s",type,pathname);

}return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值