Linux統(tǒng)計(jì)目錄內(nèi)的文件 c語(yǔ)言

readdir函數(shù)的使用方式

頭文件:
#include <sys/types.h>  
#include <dirent.h>
定義函數(shù):
struct dirent * readdir(DIR * dir);

函數(shù)說(shuō)明:
返回值:成功則返回下個(gè)目錄進(jìn)入點(diǎn)恕出。有錯(cuò)誤發(fā)生或讀取到目錄文件尾則返回NULL.
結(jié)構(gòu)體dirent 定義如下(在linux下搜索dirent.h即可找到):

struct dirent
  {
#ifndef __USE_FILE_OFFSET64
    __ino_t d_ino;
    __off_t d_off;
#else
    __ino64_t d_ino;
    __off64_t d_off;
#endif
    unsigned short int d_reclen;
    unsigned char d_type;
    char d_name[256];       /* We must not include limits.h! */
  };

調(diào)用opendir和readdir函數(shù)對(duì)指定目錄進(jìn)行遍歷操作非区,然后打印輸出指定目錄中各種類型的文件數(shù)目搪桂。

#include <stdio.h>
#include <fcntl.h>
#include <dirent.h>
#include <limits.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>

typedef int Myfunc(const char *, const struct stat *, int);   //定義一個(gè)函數(shù)
static Myfunc myfunc;
static int myftw(char *, Myfunc *);
static int dopath(Myfunc *);
static long nreg, ndir, nblk, nchr, nfifo, nslink, nsock, ntot;
//各種類型的文件數(shù)目對(duì)應(yīng)的變量
char *path_alloc(int* size);

int main(int argc, char *argv[])
{
  int ret;
  if (argc != 2)
  {
     printf("請(qǐng)輸入正確的參數(shù)!\n");   //參數(shù)錯(cuò)誤
     return 1;
  }
  ret = myftw(argv[1], myfunc);     /* does it all */
  ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock;
  //計(jì)算文件總量
  if (ntot == 0)     //如果目錄中沒(méi)有文件則將ntot設(shè)置為1以避免除數(shù)為0
  {
    ntot = 1;   
  }
  //以下一次打印各種類型文件的數(shù)據(jù)
  printf("普通文件 = %7ld, %5.2f %%\n", nreg, nreg*100.0/ntot);
  printf("目錄文件 = %7ld, %5.2f %%\n", ndir,ndir*100.0/ntot);
  printf("塊設(shè)備文件 = %7ld, %5.2f %%\n", nblk,nblk*100.0/ntot);
  printf("字設(shè)備文件 = %7ld, %5.2f %%\n", nchr, nchr*100.0/ntot);
  printf("FIFOs = %7ld, %5.2f %%\n", nfifo,nfifo*100.0/ntot);
  printf("符號(hào)鏈接文件 = %7ld, %5.2f %%\n", nslink, nslink*100.0/ntot);
  printf("套接字文件 = %7ld, %5.2f %%\n", nsock,nsock*100.0/ntot);
  return ret;
}
//路徑緩沖區(qū)分配函數(shù)
char *path_alloc(int* size)
{
  char *p = NULL;
  if(!size)
  { 
    return NULL;
  }
  p = malloc(256);
  if(p)
  {
    *size = 256;
  }
  else
  {
    *size = 0;
  }
  return p;
}

#define FTW_F   1       //
#define FTW_D   2       //目錄
#define FTW_DNR 3       //不能讀的目錄
#define FTW_NS  4       //不能獲得狀態(tài)的文件

static char *fullpath;  //存放每個(gè)文件完整路徑

static int myftw(char *pathname, Myfunc *func)
{
  int len;
  fullpath = path_alloc(&len);  //給路徑緩沖區(qū)分配一個(gè)長(zhǎng)度
  strncpy(fullpath, pathname, len); //復(fù)制文件名稱
  fullpath[len-1] = 0;  //給緩沖區(qū)的最后一位賦'\0'        
  return(dopath(func));
}

//獲得文件的狀態(tài)的函數(shù)
static int dopath(Myfunc* func)
{
  struct stat   statbuf;
  struct dirent *dirp;
  DIR *dp;
  int ret;     //返回標(biāo)記值诈悍,用于
  char *ptr;  //用于給fullpath加字符串,用來(lái)做子目錄探索
  if (lstat(fullpath, &statbuf) < 0)    //獲得文件狀態(tài)失敗就執(zhí)行,其中l(wèi)stat函數(shù)成功執(zhí)行時(shí)外盯,返回0惭墓。失敗返回-1
  {
    return(func(fullpath, &statbuf, FTW_NS));//工作正常時(shí)返回值為0
  }
  if (S_ISDIR(statbuf.st_mode) == 0)    //如果不是目錄,則。膘融。芙粱。
  {                                   //其中S_ISDIR為宏函數(shù),用于判斷是否目錄托启,如果是目錄宅倒,返回值為1
    return(func(fullpath, &statbuf, FTW_F));//工作正常時(shí)返回值為0
  }
  if ((ret = func(fullpath, &statbuf, FTW_D)) != 0)//經(jīng)過(guò)以上if語(yǔ)句,運(yùn)行到這一步的為目錄文件,調(diào)用myfunc函數(shù)屯耸,目錄記錄數(shù)+1,然后記錄成功的話拐迁,ret的值為0,if中的語(yǔ)句就不會(huì)執(zhí)行
  {          
    return(ret);//myfunc工作正常時(shí)返回值ret為0
  }
  ptr = fullpath + strlen(fullpath);    //指向路徑緩沖區(qū)字符串的結(jié)尾,此時(shí)*ptr='/0'
  *ptr++ = '/'; //相當(dāng)于*ptr='/';ptr++;
  *ptr = 0;//當(dāng)前位置'\0'疗绣,用于字符串結(jié)尾定位线召,防止輸出亂碼
  //---------------------------------------------------------------------------------------------------------------
  //獲得子目錄文件的信息
  if ((dp = opendir(fullpath)) == NULL) //調(diào)用opendir,其返回值為一個(gè)DIR類型指針多矮,如果值為NULL則讀取錯(cuò)誤或位于目錄尾
  {
    return(func(fullpath, &statbuf, FTW_DNR));//調(diào)用myfunc函數(shù)缓淹,不可讀的目錄+1
  }
  while ((dirp = readdir(dp)) != NULL) /*關(guān)鍵點(diǎn)!塔逃!readdir函數(shù)返回指向dirent結(jié)構(gòu)體類型的指針,返回值:成功則返回下個(gè)目錄進(jìn)入點(diǎn). 有錯(cuò)誤發(fā)生或讀取到目錄文件尾則返回NULL.  */
  {
        if (strcmp(dirp->d_name, ".") == 0  ||strcmp(dirp->d_name, "..") == 0)//strcmp函數(shù)讯壶,如果兩個(gè)字符串相同則返回0
                continue;                   /* 忽略.. 和. 文件 */
        strcpy(ptr, dirp->d_name);  /*把子文件名加入到*fullpath字符串后面,生成新的詳細(xì)路徑*/
        if ((ret = dopath(func)) != 0)      /* 嵌套獲取當(dāng)前的路徑的信息湾盗,如果有多個(gè)子目錄或者多個(gè)子文件伏蚊,都進(jìn)行統(tǒng)計(jì) */
            break;//if語(yǔ)句是為了讓程序運(yùn)行出錯(cuò)就跳出當(dāng)前循環(huán)
    }
  //---------------------------------------------------------------------------------------------------------------
  ptr--;
    ptr = 0;    /* 通過(guò)給斜線處賦值為'\0',相當(dāng)于刪除斜線后面添加的內(nèi)容,此處書(shū)上是ptr[-1]=0 */

    if (closedir(dp) < 0)
    {
        printf("can't close directory %s\n", fullpath);
    }
    return(ret);//可能出錯(cuò)的位置
}
//統(tǒng)計(jì)函數(shù)
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\n", pathname);
        }
        break;

    case FTW_D:
        ndir++;
        break;
    case FTW_DNR:
        printf("can't read directory %s\n", pathname);
        break;
    case FTW_NS:
        printf("stat error for %s\n", pathname);
        break;
    default:
        printf("unknown type %d for pathname %s\n", type, pathname);
    }
    return(0);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市格粪,隨后出現(xiàn)的幾起案子躏吊,更是在濱河造成了極大的恐慌,老刑警劉巖帐萎,帶你破解...
    沈念sama閱讀 218,386評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件比伏,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡疆导,警方通過(guò)查閱死者的電腦和手機(jī)赁项,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)是鬼,“玉大人肤舞,你說(shuō)我怎么就攤上這事【郏” “怎么了李剖?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,704評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)囤耳。 經(jīng)常有香客問(wèn)我篙顺,道長(zhǎng)偶芍,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,702評(píng)論 1 294
  • 正文 為了忘掉前任德玫,我火速辦了婚禮匪蟀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘宰僧。我一直安慰自己材彪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布琴儿。 她就那樣靜靜地躺著段化,像睡著了一般。 火紅的嫁衣襯著肌膚如雪造成。 梳的紋絲不亂的頭發(fā)上显熏,一...
    開(kāi)封第一講書(shū)人閱讀 51,573評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音晒屎,去河邊找鬼喘蟆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛鼓鲁,可吹牛的內(nèi)容都是我干的蕴轨。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼骇吭,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼尺棋!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起绵跷,我...
    開(kāi)封第一講書(shū)人閱讀 39,230評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎成福,沒(méi)想到半個(gè)月后碾局,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,680評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡奴艾,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
  • 正文 我和宋清朗相戀三年净当,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蕴潦。...
    茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡像啼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出潭苞,到底是詐尸還是另有隱情忽冻,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評(píng)論 5 346
  • 正文 年R本政府宣布此疹,位于F島的核電站僧诚,受9級(jí)特大地震影響遮婶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜湖笨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
  • 文/蒙蒙 一旗扑、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧慈省,春花似錦臀防、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,910評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至放闺,卻和暖如春祟昭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背怖侦。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,038評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工篡悟, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人匾寝。 一個(gè)月前我還...
    沈念sama閱讀 48,158評(píng)論 3 370
  • 正文 我出身青樓搬葬,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親艳悔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子急凰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 一、Python簡(jiǎn)介和環(huán)境搭建以及pip的安裝 4課時(shí)實(shí)驗(yàn)課主要內(nèi)容 【Python簡(jiǎn)介】: Python 是一個(gè)...
    _小老虎_閱讀 5,746評(píng)論 0 10
  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,383評(píng)論 0 5
  • 文件操作 (Linux文件操作)) [文件|目錄](méi) Linux文件操作:為了對(duì)文件和目錄進(jìn)程處理猜年,你需要用到系統(tǒng)...
    JamesPeng閱讀 1,467評(píng)論 1 5
  • 在23歲之前抡锈,我也同樣懷著錯(cuò)誤的認(rèn)知。覺(jué)得20多歲大好的時(shí)光乔外,張口閉口兒女情長(zhǎng)對(duì)我這種心有猛虎的女孩來(lái)說(shuō)是嗤之以鼻...
    運(yùn)營(yíng)喵張小小閱讀 256評(píng)論 0 0
  • 作家的厲害之處就是他的語(yǔ)言能夠直擊你的心靈床三。閑來(lái)無(wú)事,把《平凡的世界》又看了一遍杨幼,再次被路遙的思緒折服撇簿,馳...
    Sunny_2075閱讀 740評(píng)論 0 2