Chinaunix首页 | 论坛 | 博客
  • 博客访问: 159228
  • 博文数量: 52
  • 博客积分: 26
  • 博客等级: 民兵
  • 技术积分: 270
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-03 17:43
文章分类
文章存档

2012年(52)

分类:

2012-05-22 13:34:42

原文地址:myls的实现 作者:草根老师

一、目录操作函数

A.打开一个目录



如果name是一个合法的目录名,opendir函数返回这个目录的句柄。返回的这个句柄主要给读目录函数readdir用的。如果是一个非法的目录名,此函数返回NULL;

B.读一个目录



readdir函数需要opendir得到的句柄,每调用一次,返回当前目录中一个文件的信息。文件信息的由struct dirent结构体进行描述。



这个结构体我们需要关注的是最后一个字段。我们可以通过它来得到这个目录都包含有哪些文件。

案例一、实现ls查看一个目录的功能

如:



注意:每个目录下至少有"."和".."这两个文件,还有一些隐藏文件。ls命令在实现时,把这些文件过滤掉了。

  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <dirent.h>

  4. int list_dir_file(DIR *dir)
  5. {
  6.     struct dirent *pdir;

  7.     while((pdir = readdir(dir)) != NULL)
  8.     {
  9.         if(strncmp(pdir->d_name,".",1) == 0 || strcmp(pdir->d_name,"..") == 0)
  10.             continue;

  11.         printf("%s ",pdir->d_name);
  12.     }
  13.         
  14.         printf("\n");
  15.     
  16.     return 0;
  17. }

  18. int main(int argc,char *argv[])
  19. {
  20.     DIR *dir;

  21.     if(argc < 2)
  22.     {
  23.         fprintf(stderr,"Usage : %s argv[1].\n",argv[0]);
  24.         return -1;
  25.     }

  26.     if((dir = opendir(argv[1])) == NULL)
  27.     {
  28.         perror("Fail to opendir");
  29.         return -1;
  30.     }

  31.     list_dir_file(dir);

  32.     return 0;
  33. }
运行的结果:



上面的结构体中还有一个字段表明当前文件的类型d_type,在linux操作系统中定义如下:



这个信息很重要,要想获取文件的属性信息,由于文件的类型不一样,调用的函数也不一样,我们可以通过这里的信息来选择不同的函数进行调用。

C.关闭一个目录



二、获取文件属性函数



这三个函数都能获取目录或文件的属性信息,若调用成功则返回0,若出错则为-1,并且设置errno。

注意:在给定一个pathname的情况下

A.stat函数返回一个与此命名文件有关的信息结构,这个信息存放在buf指针指向的内存空间

B.fstat函数获得已在描述符filedes上打开的文件的有关信息

C.lstat函数类似于stat,但是当命名的文件是一个符号链接时,lstat返回该符号链接的有关信息,而不是该符号链接引用的文件的信息。

文件的属性信息用struct stat结构体进行描述



我们来看看,当我们执行ls  -l   file 时所得到的信息



从这里我们可以看到一个文件的属性信息,包括文件的权限、文件的连接数、文件的所有者、文件说在组、文件大小、文件最后一个修改时间、文件名。

这些信息,我们都可以通过这个结构体来获得。

先来比较重要的一个字段st_mode,我们通过它可以获得文件的类型,文件的权限。在linux操作系统中给我们提供了一下宏。

A.文件的类型


B.文件的对应权限



思考: 如果我想获取当前文件的类型和当前文件所用的权限怎么操作?

我们看到在这个结构体中,我们可以获得文件的UID和GID,而ls -l列举出来的是对应的文件所有者名和所在组名 

我们可通过下面两个函数利用其ID号获得对应的名



其中struct passwd定义如下



这个结构体中第一个字段有我们想要的用户名。



其struct group定义如下:



这里面的第一个字段有我们想要的组名。

案例二、打印文件属性

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <unistd.h>
  6. #include <dirent.h>
  7. #include <pwd.h>
  8. #include <grp.h>
  9. #include <string.h>
  10. #include <time.h>

  11. int display_attribute(struct stat *p)
  12. {
  13.     struct tm *ptime;

  14.     //文件类型
  15.     switch(p->st_mode & S_IFMT)
  16.     {
  17.     case S_IFSOCK:
  18.         printf("s");
  19.         break;

  20.     case S_IFLNK:
  21.         printf("l");
  22.         break;

  23.     case S_IFREG:
  24.         printf("-");
  25.         break;

  26.     case S_IFBLK:
  27.         printf("b");
  28.         break;

  29.     case S_IFDIR:
  30.         printf("d");
  31.         break;

  32.     case S_IFCHR:
  33.         printf("c");
  34.         break;

  35.     case S_IFIFO:
  36.         printf("p");
  37.         break;
  38.     }

  39.     //文件权限
  40.     if(p->st_mode & S_IRUSR)
  41.         printf("r");
  42.     else
  43.         printf("-");

  44.     if(p->st_mode & S_IWUSR)
  45.         printf("w");
  46.     else
  47.         printf("-");

  48.     if(p->st_mode & S_IXUSR)
  49.         printf("x");
  50.     else
  51.         printf("-");

  52.     if(p->st_mode & S_IRGRP)
  53.         printf("r");
  54.     else
  55.         printf("-");

  56.     if(p->st_mode & S_IWGRP)
  57.         printf("w");
  58.     else
  59.         printf("-");

  60.     if(p->st_mode & S_IXGRP)
  61.         printf("x");
  62.     else
  63.         printf("-");


  64.     if(p->st_mode & S_IROTH)
  65.         printf("r");
  66.     else
  67.         printf("-");

  68.     if(p->st_mode & S_IWOTH)
  69.         printf("w");
  70.     else
  71.         printf("-");

  72.     if(p->st_mode & S_IXOTH)
  73.         printf("x");
  74.     else
  75.         printf("-");

  76.     putchar(' ');
  77.     
  78.     printf("%d",p->st_nlink);

  79.     putchar(' ');

  80.     printf("%s",getpwuid(p->st_uid)->pw_name);
  81.     
  82.     putchar(' ');
  83.     
  84.     printf("%s",getgrgid(p->st_gid)->gr_name);
  85.     
  86.     putchar(' ');

  87.     printf("%ld",p->st_size);
  88.     
  89.     putchar(' ');
  90.     
  91.     ptime = localtime(&(p->st_mtime));

  92.     printf("%d-%d-%d %d:%d",ptime->tm_year + 1900,ptime->tm_mon,
  93.             ptime->tm_mday,ptime->tm_hour,ptime->tm_min);

  94.     putchar(' ');
  95.     
  96.     return 0;
  97. }

  98. int main(int argc,char *argv[])
  99. {
  100.     struct stat attr;

  101.     if(argc < 2)
  102.     {
  103.         fprintf(stderr,"Usage : %s argv[1].\n",argv[1]);
  104.         return -1;
  105.     }

  106.     if(stat(argv[1],&attr) < 0)
  107.     {
  108.         perror("Fail to stat.\n");
  109.         return -1;
  110.     }

  111.     display_attribute(&attr);

  112.     printf("%s\n",argv[1]);

  113.     return 0;
  114. }
运行结果:


下面自己动手写myls吧!






阅读(927) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~