操作系统第四次实验报告:文件系统
- 朱笃信
- 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);
}
}
}
}

浙公网安备 33010602011771号