程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 用C語言實現統計一個文件夾中各種文件的比例,c語言

用C語言實現統計一個文件夾中各種文件的比例,c語言

編輯:關於C語言

用C語言實現統計一個文件夾中各種文件的比例,c語言


  《UNIX環境高級編程》中的程序清單4-7就介紹了如何實現遞歸地統計某個目錄下面的文件!我剛開始看過它的代碼後,覺得照著敲太沒意思了,所以就合上書自己寫了一遍!為此還寫了一篇博文,這是博文地址: 在linux下用C語言實現遞歸查看某個目錄中的所有文件【CSDN】!

  今天做《Unix環境高級編程》的課後題,看到題目4.11這裡提供了一種新的實現這個程序的思路,那就是每回讀到一個目錄,就通過chdir函數進入到這個目錄,然後再通過opendir函數和readdir函數來讀取這個目錄中的文件,然後一個一個分析,如果是目錄,則進行遞歸調用。如果不是目錄,則對這個文件進行計數後立刻返回!這樣一個一個分析完目錄中的所有文件之後再來進行一個chdir(".."),返回到上一級的目錄。具體的實現代碼如下:

  

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<stdlib.h>
  4 #include<errno.h>
  5 #include<linux/limits.h>
  6 #include<unistd.h>
  7 #include<sys/types.h>
  8 #include<sys/stat.h>
  9 #include<dirent.h>
 10 
 11 //所有函數的聲明
 12 typedef int MyFunc(const char *,const struct stat*,int);
 13 static MyFunc myfunc;        //定義處理文件的函數
 14 static int myftw(const char *,MyFunc *);
 15 static int dopath(MyFunc *);
 16 
 17 //定義的全局變量
 18 static char *fullpath;    //存放文件的名稱的變量
 19 static long sock_c,lnk_c,reg_c,blk_c,dir_c,chr_c,fifo_c,total_c;    //統計各種文件類型的數量
 20 
 21 //myfunc函數中需要定義的宏
 22 #define FTW_F 1        //文件類型是文件
 23 #define FTW_D 2        //文件類型是目錄
 24 #define FTW_NS 3    //一個文件不能stat
 25 #define FTW_ND 4    //一個目錄不能被讀
 26 int main(int argc,char *argv[])
 27 {
 28     if(argc != 2)
 29     {
 30     printf("Usage:%s pathname\n",argv[0]+2);
 31     exit(EXIT_FAILURE);
 32     }
 33     myftw(argv[1],myfunc);
 34     total_c = sock_c+lnk_c+reg_c+blk_c+dir_c+chr_c+fifo_c;
 35     if(0 == total_c)
 36     {
 37     total_c = 1;
 38     }
 39     printf("socket files    = %7ld, %5.2f%%\n",sock_c,sock_c*100.0/total_c);
 40     printf("link files      = %7ld, %5.2f%%\n",lnk_c,lnk_c*100.0/total_c);
 41     printf("regular files   = %7ld, %5.2f%%\n",reg_c,reg_c*100.0/total_c);
 42     printf("block files     = %7ld, %5.2f%%\n",blk_c,blk_c*100.0/total_c);
 43     printf("directory files = %7ld, %5.2f%%\n",dir_c,dir_c*100.0/total_c);
 44     printf("character files = %7ld, %5.2f%%\n",chr_c,chr_c*100.0/total_c);
 45     printf("FIFO files      = %7ld, %5.2f%%\n",fifo_c,fifo_c*100.0/total_c);
 46     printf("total files     = %7ld, %5.2f%%\n",total_c,total_c*100.0/total_c);
 47 
 48     return 0;
 49 }
 50 static int myftw(const char* pathname,MyFunc *pmyfunc)
 51 {
 52     int ret;
 53 
 54     fullpath = (char *)malloc(sizeof(char)*PATH_MAX);
 55     strcpy(fullpath,pathname);
 56     ret = dopath(myfunc);
 57     free(fullpath);
 58 
 59     return ret;
 60 }
 61 static int dopath(MyFunc *pmyfunc)
 62 {
 63     int ret;
 64     struct stat statbuf;
 65     char *ptr;
 66     DIR *dp;
 67     struct dirent* dirp;
 68 
 69     if(-1 == lstat(fullpath,&statbuf))
 70     {
 71     ret = pmyfunc(fullpath,&statbuf,FTW_NS);
 72     return ret;
 73     }
 74     if(S_ISDIR(statbuf.st_mode) != 1)
 75     {
 76     ret = pmyfunc(fullpath,&statbuf,FTW_F);
 77     return ret;
 78     }
 79 
 80     //使目錄文件++
 81     if(0 != (ret=pmyfunc(fullpath,&statbuf,FTW_D)))
 82     return ret;
 83 
 84     //如果是目錄文件則進入這個目錄
 85     if(-1 == chdir(fullpath))
 86     {
 87     printf("%s[chdir]%s\n",fullpath,strerror(errno));
 88     ret == -1;
 89     return ret;
 90     }
 91 
 92     //打開當前目錄
 93     if(NULL == (dp=opendir(".")))
 94     {
 95     ret = pmyfunc(fullpath,&statbuf,FTW_ND);
 96     return ret;
 97     }
 98     while(NULL != (dirp=readdir(dp)))
 99     {
100     //忽略.和..文件(dot)
101     if(0==strcmp(dirp->d_name,".") || 0==strcmp(dirp->d_name,".."))
102         continue;
103     memset(fullpath,0,PATH_MAX);
104     strcpy(fullpath,dirp->d_name);
105 
106     if(0 != (ret=dopath(myfunc)))    //進行遞歸
107         break;
108     }
109     chdir("..");    //將當前目錄設置為上一級目錄
110     //對關閉文件進行判斷
111     if(-1 == closedir(dp))
112     {
113     printf("不能關閉%s\nError:%s",fullpath,strerror(errno));
114     }
115 
116     return ret;
117 }
118 static int myfunc(const char * pathname,const struct stat * statptr,int type)
119 {
120     switch(type)
121     {
122     case FTW_F:
123     switch(statptr->st_mode & S_IFMT)
124     {
125     case S_IFSOCK:    sock_c++;    break;
126     case S_IFLNK:    lnk_c++;    break;
127     case S_IFREG:    reg_c++;    break;
128     case S_IFBLK:    blk_c++;    break;
129     case S_IFCHR:    chr_c++;    break;
130     case S_IFIFO:    fifo_c++;    break;
131     case S_IFDIR:
132         printf("Error:這裡不應該出現目錄文件%s!\n\nError:%s\n",pathname,strerror(errno));
133         break;
134     }
135     break;
136     case FTW_D:
137     dir_c++;    break;
138     case FTW_ND:
139     printf("不能打開目錄%s\nError:%s\n",pathname,strerror(errno));
140     break;
141     case FTW_NS:
142     printf("不能打開文件%s\nError:%s\n",pathname,strerror(errno));
143     break;
144     }
145     return 0;
146 }

  我這個代碼並不是我自己合上書寫的,而是在W.Richard Stevens書中給出的代碼的基礎上改的!在此要特別感謝這些真正的大神給我們提供了這麼優秀的書籍!這是這個程序的運行結果,

  那個第一行是我特意設置的,那個root是一個文件夾的名字,是屬於root用戶的,所以我這裡並不能讀取,會報出一個錯誤!下面是這個改進後的程序和原來書中的程序的一個對比,發現效率還真的是提高不少啊!

  那個descend_hierarchy_p的那個程序是書上給的程序,每回讀取都是讀取的絕對路徑的名稱!而那個descend_hierarchy_ch命令就是每回碰到一個目錄就進入到那個文件夾中,然後再來讀取,這樣每回讀取的時候讀取的就是相對路徑的名稱了!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved