dirent_DIR and opendir()_readdir()_rewinddir()_telldir_seekdir()_closedir()

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 argumentdirp.

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中。

总体就是这样一种逐步细化的过程,在这一过程中,三种结构体扮演着不同的角色。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值