操作系统第四次实验报告:文件系统
- 朱笃信
- 201821121021
- 计算1811
1. 编写程序
#include<stdio.h> #include<malloc.h> #include<string.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<stdlib.h> #include<dirent.h> #include<grp.h> #include<pwd.h> #include <time.h> #define NAME_SIZE 20 struct fnode { struct fnode *next; char name[NAME_SIZE]; //文件名 }; struct fnode* insert_list(struct fnode *temp , struct fnode *linklist) //向文件中添加路径 { if(linklist == NULL) { linklist = temp ; } else { struct fnode *node ; node = linklist ; while(node->next != NULL) { node = node->next ; } node->next = temp ; } return linklist ; } void output(struct fnode *head) //打印文件信息 { struct fnode *temp = head; struct passwd *pw; struct group *group; char type[7] = {'p' , 'c' , 'd' , 'b' , '-' , 'l' , 's'}; //文件类型 char *perm[8] = {"---" , "--x" , "-w-" , "-wx" , "r--" , "r-x" , "rw-" , "rwx"}; //权限类型 while(temp != NULL) { struct stat mystat; if(stat(temp->name,&mystat) == -1) { perror("stat"); exit(EXIT_FAILURE); } printf("%4d ",mystat.st_mode); int index=((mystat.st_mode >> 12) & 0xF) / 2; //查询文件类型 printf("%c",type[index]); printf("%s",perm[mystat.st_mode >> 6 & 07]); //本人权限 printf("%s",perm[mystat.st_mode >> 3 & 07]); //组员权限 printf("%s ",perm[mystat.st_mode >> 0 & 07]); //他人权限 printf("%4ld ",mystat.st_nlink); //硬连接个数 pw=getpwuid(mystat.st_uid); //通过uid获取passwd数据 printf("%10s ",pw->pw_name); group=getgrgid(mystat.st_gid); //通过gid获取组数据 printf("%10s ",group->gr_name); printf("%8ld ",mystat.st_size); //文件大小 char buf[30]; memset(buf,'\0',30) ; ctime_r(&mystat.st_mtime,buf); //上一次被修改的时间 buf[16] ='\0'; printf("%s ", buf); printf(" %s\n",temp->name); //文件相对路径 temp = temp->next ; } } int main() { char path[]={"./"}; struct fnode *linklist = NULL; //初始化链表 struct stat stat_info; DIR *dirp = NULL; struct dirent *entp = NULL; if(stat(path, &stat_info) == -1) //获取文件属性 { perror("stat"); exit(EXIT_FAILURE); } dirp = opendir(path); //打开当前路径 if(dirp == NULL) { perror("open dir"); exit(EXIT_FAILURE); } while(entp = readdir(dirp)) //依次读取目录下的文件 { struct fnode *temp = (struct fnode *)malloc(sizeof(struct fnode)); if(temp == NULL) { perror("malloc"); exit(EXIT_FAILURE); } temp->next = NULL; memset(temp->name,'\0',NAME_SIZE); //清除节点数据 memcpy(temp->name,entp->d_name,strlen(entp->d_name)); //赋予新数据 linklist = insert_list(temp,linklist); //加入链表 } closedir(dirp) ; output(linklist) ; //free struct fnode *temp; temp = linklist; while(temp != NULL) { temp = linklist->next; free(linklist); linklist = temp; } return 0; }
2. 分析运行结果
ls -lai执行结果:
本代码执行结果:
本次实验思路:
通过读取当前路径下的所有文件,将其相对路径加入链表中,以供后续根据相对路径查询文件相关信息。
显示内容有八个字段,即查询结果包含文件的八个属性信息,
第一个字段为文件索引号,通过st_mode可以查找到。
第二个字段为文件权限,其中首字符为文件类型,其后九个字符三个为一组,分别代表本人权限,组员权限,他人权限。可以通过文件索引号进行查询。
第三个字段为硬连接个数,通过st_nlink可以查询。
第四个字段为文件在etc/passwd文件中对应的用户信息。通过getpwuid(stat.st_uid)可以查询到。
第五个数据为文件对应的组信息,通过getgrgid(stat.st_gid)可以查询到。
第六个为文件大小st_size反映的正是该信息。
第七个为文件上一次被修改的时间,通过st_mtime可以反映该信息。
第八个为文件相对路径,使用链表存储信息即可显示。
3. 通过该实验产生新的疑问及解答
从显示结果上看,很容易发现自己写的代码结果相较于ls执行执行的结果显得更为无序,本想通过readdir查看是否有通过文件名有序读取,但是经查验发现该想法并不能通过已有函数进行实现,智能通过对链表内容进行排序从而实现文件的有序读取。
此处列出冒泡排序算法,其他算法亦可:
void ListSort(node **head) { Node *p = NULL; Node *q = NULL; Node *t = NULL; if(*head == NULL || (*head)->next == NULL) { return 0; } for(p = *head; p != NULL; p = p->next) { for(q = *head; q->next != NULL; q = q->next) { if(q->name > q->next->name) { swap(q->name, q->next->name); } } } }