opendir、readdir和closedir函数
注意:在Linux中,目錄的輸入格式:/mnt//fghs、/mnt/fghs、/mnt/fghs和/mnt/fghs//是等效的,都一樣。
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
DIR *fdopendir(int fd);
返回值:出錯(cuò)返回NULL,并可以通過perror函數(shù)查看詳細(xì)錯(cuò)誤信息;成功,則返回一個(gè)DIR *類型的指針,該指針指向一個(gè)DIR類型的結(jié)構(gòu)體,該結(jié)構(gòu)體描述了所打開的目錄的一些信息??梢灶惐萶pen函數(shù):FILE * fp=open( );打開一個(gè)文件,則返回一個(gè)FILE *類型的指針:包含了文件描述符、文件讀寫指針和I/O緩沖區(qū)三部分。則打開一個(gè)目錄,返回一個(gè)DIR *類型的指針(目錄指針),利用該指針可以對(duì)打開的目錄進(jìn)行讀操作和關(guān)閉該目錄。
?
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
作用:讀一個(gè)打開了的目錄,該函數(shù)可以自動(dòng)遍歷目錄內(nèi)部所有的文件,一個(gè)個(gè)自動(dòng)進(jìn)行遍歷,直到全部遍歷完。
返回值:成功,則返回一個(gè)struct dirent *類型的指針,指向struct dirent *結(jié)構(gòu)體,該結(jié)構(gòu)體包含了該目錄中某一個(gè)文件的詳細(xì)信息,包括:
struct dirent
{
??? ino_t ??d_ino; ?// 此目錄進(jìn)入點(diǎn)(該文件)的inode
??? ff_t ???d_off;? // 目錄文件開頭至此目錄進(jìn)入點(diǎn)的位移(目錄內(nèi)文件為1,目錄內(nèi)的目錄內(nèi)部文件為2等等)
??? signed short int ??d_reclen; ??// d_name 的長度, 不包含NULL字符(0、\0)
? ??unsigned char?? ?d_type;????? // d_name 所指的文件類型
??? har? ?d_name[256];??? ?????? // 文件名(字符串類型)
};??? ?//后兩個(gè)成員常用,記住!!
對(duì)于d_type的說明(宏定義):DT_BLK 塊設(shè)備文件 ??DT_CHR 字符設(shè)備? DT_DIR 目錄文件? DT_LNK 軟鏈接文件? DT_FIFO管道文件?? DT_REG? 普通文件??? DT_SOCK? 套接字文件???? DT_UNKNOW? 未知?? ?-D_BSD_SOURCE 編譯時(shí)添加宏定義
則遍歷到哪一個(gè)文件,則就返回該文件對(duì)應(yīng)的struct dirent結(jié)構(gòu)體。遍歷完目錄內(nèi)部的最后一個(gè)文件后,會(huì)返回NULL,因此判斷一個(gè)目錄是否遍歷完,判斷其返回值是否為NULL即可,此時(shí)不代表出錯(cuò),因此不會(huì)改變errno的值。若函數(shù)出錯(cuò),也會(huì)返回NULL,且會(huì)修改errno的值。
?
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);
作用:關(guān)閉目錄文件? 注意,打開目錄后,不要忘記關(guān)閉。
返回值:0 成功? -1失敗
?
//遞歸讀一個(gè)目錄,統(tǒng)計(jì)一個(gè)目錄內(nèi)部所有普通文件的個(gè)數(shù)(注意是遞歸,包括子目錄)。
[root@localhost dir_op]# vim read_file_num.c
#include <stdio.h> #include <stdlib.h> #include <string.h>int countFileNum( const char * ); //函數(shù)聲明int countFileNum( const char *dirName ) //定義一個(gè)統(tǒng)計(jì)普通文件數(shù)目的函數(shù) {DIR *dir=NULL;dir = opendir(dirName); //打開需要統(tǒng)計(jì)的目錄if( dir == NULL ){perror("opendir");exit(1);}struct dirent *fx = NULL;fx = readdir( dir ); //讀該目錄,注意是每讀一次,就自動(dòng)遍歷到下一個(gè)文件,因此必須要讀一次,才能遍歷到下一個(gè)文件。if( fx == NULL ){perror("readdir");exit(1);}int total=0;char buff[1024]={0}; //建立緩沖區(qū)while( fx ) //fx為NULL,則循環(huán)結(jié)束{if( strcmp(fx->d_name , ".") == 0 || strcmp( fx->d_name , "..") == 0 ){fx = readdir( dir ); //必須讀一次,否則陷入死循環(huán)continue;} //字符串比較函數(shù),排除.和..(當(dāng)前目錄和上級(jí)目錄)if( fx->d_type == DT_DIR ) //如果是目錄文件,則遞歸調(diào)用,注意遞歸思想{sprintf( buff,"%s/%s",dirName,fx->d_name ); //d_name只是目錄本身的名字,不包含路勁(上級(jí)目錄等)total += countFileNum( buff );}if( fx->d_type == DT_REG )total++;fx = readdir( dir ); //必須要讀一次,否則不會(huì)遍歷下一個(gè)文件}int qw = 0;qw = closedir(dir);if( qw==-1 ){perror("closedir");exit(1);} //關(guān)閉目錄return total; }int main( int argc , char *argv[ ] ) {if( argc < 2 ){printf( "./a.out dirName\n");exit(1);}int num = 0;num = countFileNum( argv[1] );printf( " the number of reg file is %d.\n",num);return 0; }[root@localhost dir_op]# gcc -pipe -Wall -pedantic -ggdb3 read_file_num.c -o read_file_num
[root@localhost dir_op]# ls
a.out? chdir? chdir.c? fileNum? fileNum.c? haha.c? hehe.c? mkdir.c? mytest? opendir.c? readdir.c? read_file_num? read_file_num.c
[root@localhost dir_op]# ./read_file_num .
?the number of reg file is 13. ??//成功統(tǒng)計(jì)出當(dāng)前目錄中的普通文件數(shù)為13.
總結(jié)
以上是生活随笔為你收集整理的opendir、readdir和closedir函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 老爸向前冲剧情介绍
- 下一篇: fcntl函数(网络编程会用)