实验二文件系统实验报告一.实验简介本实验要求在假设的I/O 系统之上开发一个简单的文件系统,这样做既能让实验者对文件系统有整体了解,又避免了涉及过多细节。
用户通过create, open, read 等命令与文件系统交互。
文件系统把磁盘视为顺序编号的逻辑块序列,逻辑块的编号为0 至L-1。
I/O 系统利用内存中的数组模拟磁盘。
实际物理磁盘的结构是多维的:有柱面、磁道、扇区等概念。
I/O 系统的任务是隐藏磁盘的结构细节,把磁盘以逻辑块的面目呈现给文件系统。
逻辑块顺序编号,编号取值范围为0 至L .. 1,其中L 表示磁盘的存储块总数。
实验中,我们可以利用字符数组ldisk[L][B] 构建磁盘模型,其中B 表示每个存储块的长度。
I/O 系统从文件系统接收命令,根据命令指定的逻辑块号把磁盘块的内容读入命令指定的内存区域,或者把命令指定的内存区域内容写入磁盘块。
我设计的文件系统拥有三个用户。
二.具体说明1.文件系统的组织:磁盘的前k 个块是保留区,其中包含如下信息:位图和文件描述符。
位图用来描述磁盘块的分配情况。
位图中的每一位对应一个逻辑块。
创建或者删除文件,以及文件的长度发生变化时,文件系统都需要进行位图操作。
前k 个块的剩余部分包含一组文件描述符。
每个文件描述符包含如下信息:•文件长度,单位字节•文件分配到的磁盘块号数组。
该数组的长度是一个系统参数。
在实验中我们可以把它设置为一个比较小的数,例如3。
2.目录:我们的文件系统中仅设置一个目录,该目录包含文件系统中的所有文件。
除了不需要显示地创建和删除之外,目录在很多方面和普通文件相像。
目录对应0 号文件描述符。
初始状态下,目录中没有文件,所有,目录对应的描述符中记录的长度应为0,而且也没有分配磁盘块。
每创建一个文件,目录文件的长度便增加一分。
目录文件的内容由一系列的目录项组成,其中每个目录项由如下内容组成:•文件名•文件描述符序号3.对文件的操作:文件系统需提供如下函数;create, destroy, open, read, write。
•create(filename): 根据指定的文件名创建新文件。
•destroy(filename): 删除指定文件。
•open(filename): 打开文件。
该函数返回的索引号可用于后续的read, write, lseek, 或close 操作。
•close(index): 关闭制定文件。
•read(index, mem_area, count): 从指定文件顺序读入count 个字节mem_area 指定的内存位置。
读操作从文件的读写指针指示的位置开始。
•write(index, mem_area, count): 把mem_area 指定的内存位置开始的count 个字节顺序写入指定文件。
写操作从文件的读写指针指示的位置开始。
•lseek(index, pos): 把文件的读写指针移动到pos 指定的位置。
pos是一个整数,表示从文件开始位置的偏移量。
文件打开时,读写指针自动设置为0。
每次读写操作之后,它指向最后被访问的字节的下一个位置。
lseek 能够在不进行读写操作的情况下改变读写指针能位置。
•directory: 列表显示所有文件及其长度。
三.实验过程创建文件create:此时显示文件中的文件:文件的删除delete:打开文件(open):文件的写操作(write):读文件(read):关闭文件(close):退出系统(exit):四.实验代码#include <stdio.h>#include <malloc.h>#include <stdlib.h>#include <string.h>#define NULL 0typedef struct mdf{//MDF结构体char username[20];//用户名char filename[20];//文件名struct mdf *next;}MDF;typedef struct ufd{//UFD结构体char filename[20];//文件名int protect;//文件保护码unsigned int length;//文件长度struct ufd *next;}UFD;typedef struct afd{//AFD结构体char filename[20];//文件名int protect;//文件保护码unsigned int point;//文件读写指针struct afd *next;}AFD;MDF *pmdf;//全局链表头指针UFD *pufd;AFD *pafd;char UserUFD[20];//已经登陆成功的用户名void initMDF()//初始化MDF表{FILE *fp;pmdf= (MDF*)malloc(sizeof(MDF));MDF *p = pmdf;if((fp = fopen("MDF", "r+")) == NULL){//打开MDF文件puts("the MDF cannot open!\n");exit(1);}while (!feof(fp)){//把MDF文件中的内容装入链表p->next = (MDF*)malloc(sizeof(MDF));p = p->next;fscanf(fp, "%s", p->username);fscanf(fp, "%s", p->filename);}p->next = NULL;fclose(fp);}void printUFD()//打印MDF表{UFD *p = pufd->next;puts("文件名\t\t保护码\t\t文件长度\n");while (p){printf("%s", p->filename);printf("\t\t%d" , p->protect);printf("\t\t%d\n", p->length);p=p->next;}}void initUFD(char *name)//初始化UFD表{FILE *fp;pufd= (UFD*)malloc(sizeof(UFD));UFD *p = pufd;if((fp = fopen(name, "r+")) == NULL){puts("the UFD cannot open!\n");exit(1);}while (!feof(fp)){//建立UFD链表p->next = (UFD*)malloc(sizeof(UFD));p = p->next;fscanf(fp, "%s", p->filename);fscanf(fp, "%d", &p->protect);fscanf(fp, "%d", &p->length);fgetc(fp);}p->next = NULL;fclose(fp);}int checkuser()//检测登陆的用户名{char username[20];while(1){puts("请输入用户名: \n");scanf("%s", username);MDF *p = pmdf;while(p){if(strcmp(username, p->username) == 0){strcpy(UserUFD, p->filename);initUFD(p->filename);printUFD();return 1;}p= p->next;}puts("同户名不存在\n");}}void initAFD()//初始化AFD{pafd = (AFD*)malloc(sizeof(AFD));pafd->next = NULL;}bool create()//创建文件命令{char filename[20];UFD *p = pufd->next;AFD *pa = pafd;puts("请输入要创建的文件名: \n");scanf("%s", filename);while (p){if(strcmp(filename, p->filename) == 0){puts("此文件已经存在了!\n");return 0;}if(!p->next)break;p= p->next;}p->next = (UFD*)malloc(sizeof(UFD));p=p->next;strcpy(p->filename, filename);p->protect = 2;p->length = 0;p->next = NULL;while(pa->next){//创建文件后加入到AFD pa=pa->next;}pa->next = (AFD*)malloc(sizeof(AFD));pa = pa->next;strcpy(pa->filename ,filename);pa->protect = 2;pa->point = 0;pa->next = NULL;return 1;}bool _delete()//删除文件命令{char filename[20];puts("请输入要删除的文件名: \n");scanf("%s", filename);UFD *p = pufd;UFD *temp;while (p->next){if(strcmp(filename, p->next->filename) == 0){ temp = p->next;p->next = p->next->next;free(temp);printf("文件%s删除成功!\n", filename);return 1;}p= p->next;}puts("要删除的文件不存在!\n");return 0;}bool open()//打开文件命令{char filename[20];unsigned int protect;puts("请输入要打开的文件名: \n");scanf("%s", filename);puts("请输入要打开的文件保护类型: \n");scanf("%d", &protect);UFD *p = pufd->next;AFD *pa = pafd->next;while (pa){if(strcmp(filename, pa->filename) == 0){printf("文件%s已经打开!\n",filename);return 1;}if(!pa->next)break;pa = pa->next;}if(!pa)pa=pafd;while (p){if(strcmp(filename, p->filename) == 0){pa->next = (AFD*)malloc(sizeof(AFD));pa = pa->next;strcpy(pa->filename , p->filename);pa->protect = protect;if(protect == 1)pa->point = 0;elsepa->point = p->length;pa->next=NULL;printf("文件%s已经打开!\n",filename);return 1;}p= p->next;}puts("要打开的文件不存在!\n");return 0;}void close()//关闭文件命令{char filename[20];UFD *pu = pufd->next;puts("请输入要关闭的文件名: \n");scanf("%s", filename);AFD *p = pafd;AFD *temp;while (p&&p->next){if(strcmp(filename, p->next->filename) == 0){temp = p->next;p->next = p->next->next;if(temp->protect == 2){while(pu){if(strcmp(temp->filename, pu->filename) == 0){pu->length =temp->point;break;}pu = pu->next;}}free(temp);printf("文件%s关闭成功!\n", filename);return ;}p= p->next;}puts("要关闭的文件没有被打开!\n");}int read()//读文件命令{char filename[20];unsigned int length;AFD *p = pafd->next;puts("请输入要读的文件名: \n");scanf("%s", filename);puts("请输入要读的长度\n");scanf("%d", &length);while (p){if(strcmp(filename, p->filename) == 0){p->point += length;printf("文件%s读取成功!\n", filename);return 1;}p= p->next;}puts("读取失败文件没有打开过!\n");return 0;}int write()//写文件命令{char filename[20];unsigned int length;AFD *p = pafd->next;puts("请输入要写的文件名: \n");scanf("%s", filename);while (p){if(strcmp(filename, p->filename) == 0){if(p->protect != 2){printf("文件%s不可写!\n", filename);return 0;}puts("请输入要写的长度\n");scanf("%d", &length);p->point += length;printf("文件%s写入成功!\n", filename);return 1;}p= p->next;}puts("写入失败文件没有打开过!\n");return 0;}void destroy()//释放内存{MDF *pm = pmdf;while(pm){pmdf = pmdf->next;free(pm);pm = pmdf;}AFD *pa = pafd;while(pa){pafd = pafd->next;free(pa);pa = pafd;}UFD *pu = pufd;while(pu){pufd = pufd ->next;free(pu);pu = pufd;}}void saveUFD()//保存UFD文件{FILE *fp;UFD *p = pufd->next;if((fp = fopen(UserUFD, "w")) == NULL){ puts("the UFD cannot open!\n");exit(1);}while (p){fprintf(fp, "%s", "\n");fprintf(fp, "%s%s", p->filename,"\t\t");fprintf(fp, "%d%s", p->protect,"\t\t");fprintf(fp, "%d", p->length);p=p->next;}fclose(fp);}void exit()//推出系统{AFD *pa = pafd->next;UFD *pu = pufd->next;while(pa){if(pa->protect == 2){while(pu){if(strcmp(pa->filename, pu->filename) == 0){pu->length = pa->point;break;}pu = pu->next;}}pa =pa->next;}saveUFD();printUFD();destroy();}void operate()//命令识别{while(1){char command[20];char name[][8] = {"create", "delete", "open", "close","read", "write","exit"};puts("请输入命令: \n");scanf("%s", command);if(strcmp(command, name[0] ) == 0)create();else if(strcmp(command, name[1] ) == 0)_delete();else if(strcmp(command, name[2] ) == 0)open();else if(strcmp(command, name[3] ) == 0)close();else if(strcmp(command, name[4] ) == 0)read();else if(strcmp(command, name[5] ) == 0)write();else if(strcmp(command, name[6] ) == 0){exit();return;}elseputs("无效命令,请重新输入:\n");}}void print(){puts("文件系统\n");puts("***使用说明***:\n");puts("本文件系统共有三个用户分别是user1 user2 user3\n\系统命令有create, delete, open, close,read, write,exit\\nexit----------------------------------------退出系统"); }int main(){print();initMDF();checkuser();initAFD();operate();//命令识别return 0;}。