1. dirent --- 用来表示某文件夹的目录内容。
我猜是directory content 的缩写.
dirent 定义于 /include/bits/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! */
};
#ifdef __USE_LARGEFILE64
struct dirent64
{
__ino64_t d_ino;
__off64_t d_off;
unsigned short int d_reclen;
unsigned char d_type;
char d_name[256]; /* We must not include limits.h! */
};
#endif
可以看出64位的位宽和32位的位宽,定义有所区别,但是表示的内容还是一样的。
d_ino --- inode number 索引节点号.
d_off --- offset to this dirent 在目录文件中的偏移.
d_reclen --- length of this d_name 文件名长.
d_type --- the type of d_name 文件类型.
d_name[256] --- file name (null-terminated) 文件名
2. DIR 结构体
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;
*__fd
:'struct hurd_fd' pointer for descriptor.*__data :Directory block.
__entry_data :Entry number `ponds to.
*__ptr :Current pointer into the block.
__allocation :Space allocated for the block.
__size :Total valid data in the block.
(, __lock) :Mutex lock for this structure.
DIR结构体类似于FILE,是一个内部结构. 关于DIR结构体的内容,我们知道这么多就可以了,没必要去再去研究他的结构成员。
以下几个函数用这个内部结构保存当前正在被读取的目录的有关信息.
3. 几个 dirent, DIR相关的常用函数 opendir(),readdir(),closedir() 等.
head file:
#include<sys/types.h>
#include<dirent.h>
a. opendir()
DIR *opendir(const char *pathname)
获取pathname目录下的所由文件和目录的列表,如果path是个文件/在失败的时候则返回值为NULL
即打开文件目录,返回的就是指向DIR结构体的指针,而该指针由以下几个函数使用:
b. readdir():
struct dirent *readdir(DIR *dp);
读取opendir 返回值的那个列表, 返回dirent结构体指针.
c. rewinddir():
void rewinddir(DIR *dp);
rewinddir()用来设置参数dir目录流目前的读取位置为原来开头的读取位置,没有返回值。
example:
#include<sys/types.h>
#include<dirent.h>
#include<unistd.h>
main()
{
DIR * dir;
struct dirent *ptr;
dir = opendir(“/etc/rc.d”);
while((ptr = readdir(dir))!=NULL)
{
printf(“d_name :%s\n”,ptr->d_name);
}
rewinddir(dir);
printf(“readdir again!\n”);
while((ptr = readdir(dir))!=NULL)
{
printf(“d_name: %s\n”,ptr->d_name);
}
closedir(dir);
}
d. rewinddir():
long int telldir(DIR *dirp);
返回值记录着一个目录流的当前位置。可以利用seekdir来重置这个值
e. seekdir():
void seekdir(DIR *dirp,long int loc);
设置目录流dirp的目录项指针。loc的值用来设置指针位置,他应该通过前一个telldir调用获得.
example:
#include<unistd.h>
#include<stdio.h>
#include<sys/types.h>
#include<dirent.h>
#include<string.h>
int main(){
DIR *dirp;
struct dirent *dp;
long int loc;
dirp=opendir(“./”);
while((dp=readdir(dirp))!=NULL){
printf(“%s\n”,dp->d_name);
if(stcmp(dp->name,“123″)==0)//遍历目录的时候遇到123这个文件,则获取这个值
loc=telldir(dirp);
}
closedi(dirp);
printf(“———-分割线———-\n”);
dirp=opendir(“./”);
seekdir(dirp,loc);//设置目录流目录项指针
while((dp=readdir(dirp))!=NULL){
printf(“%s\n”,dp->d_name);
}
return (0);
}
这个执行后的结果大概如下:
.
..中间省略
123
1.c
2.c
3.c
..接着省略
——–分割线——–
.
1.c
2.c
3.c
..接着省略
什么情况,细细看的童鞋都知道了吧,不解释了!
f. closedir():
int closedir(DIR *dirp);
The
closedir() function shall close the directory stream referred to by the argument
dirp.
Upon return, the valueof dirp may no longer point to an accessible object of the typeDIR.
If a file descriptor is used to implement typeDIR, that file descriptor shall be closed.
Upon successful completion, closedir() shall return 0; otherwise, -1 shall be returned anderrno set to indicatethe error.
4. 实例代码:列出某目录下所有文件夹功能。
/*
* This is a program to show opendir(), readdir(), closedir().
* The function of the program is to list the folders under the request dir
*/
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#ifndef DT_DIR
#error "DT_DIR not defined, maybe d_type not a mumber of struct dirent!"
#endif
int main(int argc, char*argv[])
{
static char dot[] =".", dotdot[] ="..";
const char *name;
DIR *dirp;
struct dirent *dp;
if (argc == 2)
name = argv[1];
else
name = dot;
printf(" the request dir name is %s\n", name);
//open the request dir.
//return DIR pointer if open succeed.
//return NULL if opendir failed.
dirp = opendir(name);
if (dirp == NULL) {
fprintf(stderr, "%s: opendir(): %s: %s\n",
argv[0], name, strerror(errno));
exit(errno);
} else {
printf("opendir %s succeed!\n", name);
}
//readdir(dirent)
//return dirent pointer if readdir succeed.
//return NULL if readdir failed.
while ((dp = readdir(dirp)) != NULL) {
//判断文件类型是DT_DIR, 也就是目录
if (dp->d_type == DT_DIR)
//如果文件名不是"." 或者"..",就打印出来
if ( strcmp(dp->d_name, dot)
&& strcmp(dp->d_name, dotdot) )
printf("%s/\n", dp->d_name);
}
//closedir(dirent)
closedir(dirp);
return (0);
}
example2:
#include<stdio.h>
#include<dirent.h>
int main(void)
{
DIR *dirptr=NULL;
int i=1;
struct dirent *entry;
if((dirptr = opendir("test.dir"))==NULL)
{
printf("opendir failed!");
return 1;
}
else
{
while(entry=readdir(dirptr))
{
printf("filename%d=%s\n",i,entry->d_name);
i++;
}
closedir(dirptr);
}
return 0;
}
输出:
filename1=dir1
filename2=file3
filename3=..
filename4=dir3
filename5=.
filename6=file1
filename7=file2
filename8=dir2
5. 最后,总结一下,想要获取某目录下(比如a目下)b文件的详细信息,我们应该怎样做
首先,我们使用opendir函数打开目录a,返回指向目录a的DIR结构体c。
接着,我们调用readdir( c)函数读取目录a下所有文件(包括目录),返回指向目录a下所有文件的dirent结构体d。
然后,我们遍历d,调用stat(d->name,stat *e)来获取每个文件的详细信息,存储在stat结构体e中。
总体就是这样一种逐步细化的过程,在这一过程中,三种结构体扮演着不同的角色。