环境: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中。
参考: