opendir、readdir、rewinddir、closedir、telldir、seekdir、stat函数和DIR、dirent、stat结构体胡乱分析

[top]

1.opendir()

DIR结构体类似于FILE,是一个内部结构,以下几个函数用这个内部结构保存当前正在被读取的目录的有关信息(摘自《UNIX环境高级编程(第二版)》)。
函数 DIR *opendir(const char *pathname),即打开文件目录,返回的就是指向DIR结构体的指针。

#include<sys/types.h>												
#include<dirent.h>												
                                                
// 函数原型												
DIR* opendir (constchar * path );												
                                                
// 功能:打开一个目录												
// 返回值:成功则返回DIR*型态的目录流, 打开失败则返回NULL.												
                                                
// 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;												

而该指针由以下几个函数使用:

相关操作						
						
struct dirent *readdir(DIR *dp);   			读取目录流中的文件信息			
  						
void rewinddir(DIR *dp);   			        重设读取目录流的位置为开头位置			
  						
int closedir(DIR *dp);   			        关闭目录流			
  						
long telldir(DIR *dp);   			        取得目录流的读取位置			
  						
void seekdir(DIR *dp,long loc);  			设置下回读取目录流的位置			

与其他许多流一样,目录流是具有缓冲区的,而且一开始不会有数据存储在缓冲区内,或不完全存储在缓冲区内,而是等到函数调用后才会有数据进入。

2.readdir()

// 头文件
#include<sys/types.h>
#include<dirent.h>

// 函数原型
struct dirent* readdir(DIR* dp);     /* 需要循环读取dp中的文件和目录,每读取一个文件或目录都返回一个dirent结构体指针 */

// 功能:读取目录
// 返回值: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字符 */
}

3. rewinddir()

// 头文件
#include <sys/types.h>
#include <dirent.h>

// 函数原型
void rewinddir(DIR *dp);

// 功能:用来设置参数dp目录流目前的读取位置为原来开头的读取位置

4. closedir()

// 头文件
#include <sys/types.h>
#include <dirent.h>

// 函数原型
int closedir(DIR*dp);

// 功能:关闭参数dp所指的目录流
// 返回值:关闭成功则返回0,,失败返回-1

5.telldir()

// 头文件
#include <sys/types.h>
#include <dirent.h>

// 函数原型
long inttelldir(DIR *dp);

// 功能:获取当前dp位置
// 返回值:返回目录流dp的当前位置,此返回值代表距离目录文件开头的偏移量,有错误发生时返回-1

6. seekdir()

// 头文件
#include <sys/types.h>
#include <dirent.h>

// 函数原型
void seekdir(DIR *dp,long int loc);

// 功能:用来设置参数dp目录流当前的读取位置,在调用readdir()时便从此新位置开始读取。参数loc代表距离目录文件开头的偏移量。

7. stat()

// 头文件
#include <sys/stat.h>
#include <unistd.h>

// 函数原型
int stat(const char *file_name,struct stat *buf);

// 功能:通过文件名file_name获取文件信息,并保存在buf所指的结构体stat中
// 返回值:执行成功则返回0,失败返回-1

// 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;     //该文件所占的磁盘块
};

8. 示例代码:

#include <cstdio>									
#include <unistd.h>									
#include <stdio.h>									
#include <dirent.h>									
#include <string.h>									
#include <sys/stat.h>									
#include <time.h>									
#include <stdlib.h>									
//遍历一个文件夹下所有文件,并打印文件大小和日期									
									
int main()									
{									
    DIR* dp;									
    dp = opendir("/");									
    struct dirent* pdir;									
    struct stat buf;									
    char date_time[64];									
    int i = 0;									
    struct tm t;									
    if (dp)									
    {									
        while ((pdir = readdir(dp)) != NULL) {	
            printf("索引节点号:%#lx  在目录文件中的偏移量:%#lx  文件名长度:%d  文件类型:%d  文件名:%s\n",pdir->d_ino,pdir->d_off, pdir->d_reclen, pdir->d_type, pdir->d_name);           								
            i = stat(pdir->d_name, &buf);									
            strftime(date_time, sizeof(date_time), "%Y-%m-%d %H:%M:%S", localtime_r(&buf.st_atim.tv_sec, &t));									
            printf("%-15s %-10d %s\n", pdir->d_name, buf.st_size, date_time);									
        }       									
    }									
    									
    getchar();									
    return 0;									
}