一、目录操作函数
A.打开一个目录
如果name是一个合法的目录名,opendir函数返回这个目录的句柄。返回的这个句柄主要给读目录函数readdir用的。如果是一个非法的目录名,此函数返回NULL;
B.读一个目录
readdir函数需要opendir得到的句柄,每调用一次,返回当前目录中一个文件的信息。文件信息的由struct dirent结构体进行描述。
这个结构体我们需要关注的是最后一个字段。我们可以通过它来得到这个目录都包含有哪些文件。
案例一、实现ls查看一个目录的功能
如:
注意:每个目录下至少有"."和".."这两个文件,还有一些隐藏文件。ls命令在实现时,把这些文件过滤掉了。
- #include <stdio.h>
- #include <sys/types.h>
- #include <dirent.h>
- int list_dir_file(DIR *dir)
- {
- struct dirent *pdir;
- while((pdir = readdir(dir)) != NULL)
- {
- if(strncmp(pdir->d_name,".",1) == 0 || strcmp(pdir->d_name,"..") == 0)
- continue;
- printf("%s ",pdir->d_name);
- }
-
- printf("\n");
-
- return 0;
- }
- int main(int argc,char *argv[])
- {
- DIR *dir;
- if(argc < 2)
- {
- fprintf(stderr,"Usage : %s argv[1].\n",argv[0]);
- return -1;
- }
- if((dir = opendir(argv[1])) == NULL)
- {
- perror("Fail to opendir");
- return -1;
- }
- list_dir_file(dir);
- return 0;
- }
运行的结果:
上面的结构体中还有一个字段表明当前文件的类型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定义如下:
这里面的第一个字段有我们想要的组名。
案例二、打印文件属性
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #include <dirent.h>
- #include <pwd.h>
- #include <grp.h>
- #include <string.h>
- #include <time.h>
- int display_attribute(struct stat *p)
- {
- struct tm *ptime;
- //文件类型
- switch(p->st_mode & S_IFMT)
- {
- case S_IFSOCK:
- printf("s");
- break;
- case S_IFLNK:
- printf("l");
- break;
- case S_IFREG:
- printf("-");
- break;
- case S_IFBLK:
- printf("b");
- break;
- case S_IFDIR:
- printf("d");
- break;
- case S_IFCHR:
- printf("c");
- break;
- case S_IFIFO:
- printf("p");
- break;
- }
- //文件权限
- if(p->st_mode & S_IRUSR)
- printf("r");
- else
- printf("-");
- if(p->st_mode & S_IWUSR)
- printf("w");
- else
- printf("-");
- if(p->st_mode & S_IXUSR)
- printf("x");
- else
- printf("-");
- if(p->st_mode & S_IRGRP)
- printf("r");
- else
- printf("-");
- if(p->st_mode & S_IWGRP)
- printf("w");
- else
- printf("-");
- if(p->st_mode & S_IXGRP)
- printf("x");
- else
- printf("-");
- if(p->st_mode & S_IROTH)
- printf("r");
- else
- printf("-");
- if(p->st_mode & S_IWOTH)
- printf("w");
- else
- printf("-");
- if(p->st_mode & S_IXOTH)
- printf("x");
- else
- printf("-");
- putchar(' ');
-
- printf("%d",p->st_nlink);
- putchar(' ');
- printf("%s",getpwuid(p->st_uid)->pw_name);
-
- putchar(' ');
-
- printf("%s",getgrgid(p->st_gid)->gr_name);
-
- putchar(' ');
- printf("%ld",p->st_size);
-
- putchar(' ');
-
- ptime = localtime(&(p->st_mtime));
- printf("%d-%d-%d %d:%d",ptime->tm_year + 1900,ptime->tm_mon,
- ptime->tm_mday,ptime->tm_hour,ptime->tm_min);
- putchar(' ');
-
- return 0;
- }
- int main(int argc,char *argv[])
- {
- struct stat attr;
- if(argc < 2)
- {
- fprintf(stderr,"Usage : %s argv[1].\n",argv[1]);
- return -1;
- }
- if(stat(argv[1],&attr) < 0)
- {
- perror("Fail to stat.\n");
- return -1;
- }
- display_attribute(&attr);
- printf("%s\n",argv[1]);
- return 0;
- }
运行结果:
下面自己动手写myls吧!
阅读(6582) | 评论(0) | 转发(7) |