unix环境高级编程 /ls的实现,以及目录这种文件等

ls的思路:

a/  --------------->目录

  b--------------->文件名 

想要获取某目录下(比如a目下)b文件的详细信息,我们应该怎样做?

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

指向 目录a 的 DIR结构体指针c = opendir(a)                      

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

指向  目录a的所有文件  的  dirent结构体指针 d = readdir(c)

3、实现 ls 的功能

#include"apue.h"                 //作者自定义的头文件
#include<dirent.h>

int main(int argc , char *argv[])
{
    DIR  *dp;
    struct dirent *dirp;
    
    if(argc != 2){
          err_quit("usage : ls directory_name");     //作者自定义的错误处理函数
    }

    if((dp = opendir(argv[1])) == NULL)                 //dp可以看做打开目录的一个句柄(lxm)
        err_sys("can't open %s", argv[1]);              //作者自定义的错误处理函数

    while ((dirp = readdir(dp)) != NULL ){         //通过句柄来读取目录;dirp指向  的应该是该目录下第一个文件的信息DIR 结构体(readdir的返回值)
                                 //每readdir(dp)一次,dirp指向下一个文件
    printf("%s\n," dirp->d_name);              //dirp指向保存文件信息的DIR结构体,可以获取每个文件的名字。
  }
    closedir(dp);
    exit(0);
}

  

 

 

4、实现 ls -l 的功能

  如果想获得类似ls -l那种效果的文件信息,必须要靠stat函数了。

通过readdir函数读取到的文件名存储在结构体dirent的d_name成员中,而函数

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

的作用就是获取文件名为d_name的文件的详细信息,存储在stat结构体中。

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

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

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;  

  

以下几个函数 用  这个内部结构  保存  当前正在被读取的目录   的有关信息

函数 DIR *opendir(const char *pathname),即打开文件目录,返回的就是指向DIR结构体的指针,而该指针由以下几个函数使用:

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

  

dirent结构体

目录文件(directory file)的概念:这种文件包含了  其他文件的名字  以及指向与这些文件 有关的信息的  指针

dirent不仅仅指向目录,还指向目录中的具体文件,readdir函数同样也读取目录下的文件,

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同样也是起着一个索引的作用。

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

  

 

posted @ 2018-02-03 11:36  热爱世界的初学者  阅读(286)  评论(0编辑  收藏  举报