C语言遍历文件目录:readdir,opendir

环境:Linux系统

头文件:

#include<sys/types.h>
#include<dirent.h>

一、opendir

原型

DIR* opendir (const char * path );

参数与功能

path为目录路径,打开一个目录,在失败的时候返回一个空的指针。

返回值

DIR*,DIR结构体类似于FILE,是一个内部结构,以下几个函数用这个内部结构保存当前正在被读取的目录的有关信息,其内容如下:

struct __dirstream   
{   
    void *__fd;    
    char *__data;    
    int __entry_data;    
    char *__ptr;    
    int __entry_ptr;    
    size_t __allocation;    
    size_t __size;    
    __libc_lock_define (, __lock)    
};   
typedef struct __dirstream DIR;  

通过opendir函数返回的dir结构可被以下函数使用:

struct dirent *readdir(DIR *dp);    
void rewinddir(DIR *dp);   
int closedir(DIR *dp);    
long telldir(DIR *dp);   
void seekdir(DIR *dp,long loc);  

二、readdir

原型

struct dirent* readdir(DIR* dir_handle);

参数与功能

DIR* dir_handle就是opendir返回的DIR结构,readdir的功能就是读一个目录。

返回值

返回是dirent结构体指针,dirent结构体成员如下

struct dirent   
{   
  long d_ino; /* inode number 索引节点号 */     
    off_t d_off; /* offset to this dirent 在目录文件中的偏移 */  
    unsigned short d_reclen; /* length of this d_name 文件名长 */  
    unsigned char d_type; /* the type of d_name 文件类型 */  
    char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */  
}  

从上述定义也能够看出来,dirent结构体存储的关于文件的信息很少,所以dirent同样也是起着一个索引的作用,如果想获得类似ls -l那种效果的文件信息,必须要靠stat函数了。

三、stat

原型

int stat(const char *file_name, struct stat *buf);

参数与功能

file_name为readdir返回的dirent结构体中的d_name,buf为stat结构buf。

通过readdir函数读取到的文件名存储在结构体dirent的d_name成员中,而函数stat();的作用就是获取文件名为d_name的文件的详细信息,存储在stat结构体中。以下为stat结构体的定义:

struct stat {   
        mode_t     st_mode;       //文件访问权限   
        ino_t      st_ino;       //索引节点号   
        dev_t      st_dev;        //文件使用的设备号   
        dev_t      st_rdev;       //设备文件的设备号   
        nlink_t    st_nlink;      //文件的硬连接数   
        uid_t      st_uid;        //所有者用户识别号   
        gid_t      st_gid;        //组识别号   
        off_t      st_size;       //以字节为单位的文件容量   
        time_t     st_atime;      //最后一次访问该文件的时间   
        time_t     st_mtime;      //最后一次修改该文件的时间   
        time_t     st_ctime;      //最后一次改变该文件状态的时间   
        blksize_t st_blksize;    //包含该文件的磁盘块的大小   
        blkcnt_t   st_blocks;     //该文件所占的磁盘块   
};  

四、示例

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <time.h>

/* 文件大小和修改时间 */
static int get_file_size_time(const char *filename)
{
	struct stat statbuf;
	/* 判断未打开文件 */ 
	if(stat(filename,&statbuf)==-1)
	{
		printf("Get stat on %s Error: %s\n", filename, strerror(errno));
		return(-1);
	}
	if(S_ISDIR(statbuf.st_mode)) // 目录
		return(1);
	if(S_ISREG(statbuf.st_mode)) // 文件
		printf("%s size: %ld bytes\tmodified at %s", filename, statbuf.st_size, ctime(&statbuf.st_mtime));
	return(0);
}

int main(int argc,char **argv)
{
	DIR *dirp;
	struct dirent *direntp;
	int stats;

	if(argc!=2)
	{
		printf("Usage: %s filename\n\a", argv[0]);
		exit(1);
	}

	if(((stats=get_file_size_time(argv[1]))==0)||(stats==-1)) // 文件或出现错误
		exit(1);

	/* 打开目录 */	
	if((dirp=opendir(argv[1]))==NULL)
	{
		printf("Open Directory %s Error: %s\n", argv[1], strerror(errno));
		exit(1);
	}

	/* 返回目录中文件大小和修改时间 */
	while((direntp=readdir(dirp))!=NULL) 
	{
		/* 给文件或目录名添加路径:argv[1]+"/"+direntp->d_name */
		char dirbuf[512]; 
		memset(dirbuf,0,sizeof(dirbuf)); 
		strcpy(dirbuf,argv[1]); 
		strcat(dirbuf,"/"); 
		strcat(dirbuf,direntp->d_name); 
		if(get_file_size_time(dirbuf)==-1) break;
	}

	closedir(dirp);
	exit(1);
}

运行结果:

五、总结

遍历一个文件夹中内容的布奏:

首先,使用opendir函数打开目录a,返回指向目录a的DIR结构体c。

接着,我们调用readdir( c)函数读取目录a下所有文件(包括目录),返回指向目录a下所有文件的dirent结构体d。

然后,遍历d,调用stat(d->name,stat *e)来获取每个文件的详细信息,存储在stat结构体e中。

 

参考:

https://blog.csdn.net/u012349696/article/details/50083787

https://blog.csdn.net/hb707934728/article/details/52100853

  • 8
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值