C语言实现文件类型统计函数
生活随笔
收集整理的這篇文章主要介紹了
C语言实现文件类型统计函数
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
#include<dirent.h>
#include<limits.h>
#include<sys/stat.h>
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>#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);
static Myfunc 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 long nreg,ndir,nblk,nchr,nfifo,nslink,nsock,ntot;int main( int argc, char *argv[])
{int ret;if(argc != 2){printf("falut command input !\n");exit(1);}//計算各類文件的個數ret = myftw(argv[1],myfunc);ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock;//避免除以0if(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)return NULL;p = malloc(256);if(p)*size = 256;else*size = 0;return p;
}//dopath用于判斷是否是目錄,然后根據選擇情況是直接進入myfun函數取技術
//還是遞歸調用dopath函數
static int dopath(Myfunc *func)
{struct stat statbuf;struct dirent *dirp;DIR *dp;int ret,n;//調用lstat獲取路徑名的stat信息,如果不成功,調用func函數,并傳遞給FTW_NSif(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后還不會返回,會繼續執行funcif((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) //然后采用新的路徑名遞遞歸的調用dopathbreak;}fullpath[n-1] = 0;//關閉目錄if(closedir(dp) < 0 )printf("can't close directory %s",fullpath);return ret;}//通過stat結構的st_mode字段來判斷文件的類型,并計數
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: printf("for S_IFDIR for %s",pathname);}break;//對于目錄文件進行處理case FTW_D:ndir++;break;//對于不可讀目錄進行處理case FTW_DNR:printf("%s dir isn't read",pathname);break;case FTW_NS:printf("%s stat error",pathname);default:printf("%d type aren't identified, path is %s",type,pathname);}return 0;
}
?
轉載于:https://www.cnblogs.com/wanghao-boke/p/11608159.html
總結
以上是生活随笔為你收集整理的C语言实现文件类型统计函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: fgets()函数
- 下一篇: idea 创建了maven的项目,pom