《计算机操作系统》课程设计题目:二级文件系统专业:计算机科学与技术班级:姓名:学号:指导教师:时间:2011.6.01---2011.6.102011年6 月13日一、实验内容为Linux系统设计一个简单的二级文件系统。
要求做到以下几点:1.可以实现下列几条命令:login用户登录dir 列目录create创建文件delete 删除文件open 打开文件close 关闭文件read 读文件write 写文件2.列目录时要列出文件名,物理地址,保护码和文件长度二、实验目的通过一个简单多用户文件系统的设计,加深理解文件系统的内部功能及内部实现。
三、开发环境Windows操作系统Microsoft Visual C++四、分析设计实验原理通过程序模拟Linux文件系统,用一个二进制文件(FileSystem.disk)来模拟磁盘.设计一个多用户的二级文件系经统、实现一般的创建文件、目录,删除文件、目录,切换目录,打开、关闭文件、读写文件等操作。
文件系统,包含格式化,显示文件(目录),创建文件等几个简单命令的实现,而且能完成超级块的读写,节点的读写等过程. 本文件系统采用两级目录,其中第一级对应于用户账号,第二级对应于用户账号下的文件。
另外,为了简单本文件系统未考虑文件共享、文件系统安全以及管道文件与设备文件等特殊内容。
1.程序执行流程图:2.数据块的分配和回收设计FileSystem类负责管理磁盘空间和磁盘内存I节点,负责对磁盘空间和磁盘数据进行优化管理。
并提代接口言方法供用户或程序调用。
五、打印的源程序及附上的注释#include "xd.h" //文件管理void createFile(char fileName[],int length,char fileKind[]); //创建文件void fileWrite(char fileName[]); //写文件void fileCat(char fileName[]); //读文件void fileRen(char fileName[],char rename[]); //重命名文件void fileClose(char fileName[]); //关闭已打开的文件void delFile(char fileName[]); //删除文件int requestDist(int &startPostion,int maxLength); //磁盘分配查询void initDisk(); //初始化磁盘void freeDisk(int startPostion); //磁盘空间释放//用户管理void userCreate();int login();int userID=-1; //用户登录的ID号,值为-1时表示没有用户登录//用户注册void userCreate(){char c;char userName[10];int i;if(used<MaxUser){cout<<"请输入用户名:";for(i=0;c=getch();i++)if(c==13) break;elseuserName[i]=c;printf("%c",c);}userName[i]='\0';for(i=0;i<used;i++){if(!strcmp(userTable[i].userName,userName)){cout<<"\n";cout<<"该用户名已存在,创建用户失败\n";//system("pause");return;}}strcpy(userTable[used].userName,userName);cout<<"\n";cout<<"请输入密码:";for(i=0;c=getch();i++){if(c==13) break;elseuserTable[used].password[i]=c;printf("*");}userTable[used].password[i]='\0';cout<<"\n";cout<<"创建用户成功\n";used++;//system("pause");}else{cout<<"创建用户失败,用户已达到上限\n";//system("pause");}fflush(stdin);}//登录int login(){char name[10],psw[10];int i,times;cout<<"请输入用户名:";for(i=0;c=getch();i++){if(c==13) break;elsename[i]=c;printf("%c",c);}name[i]='\0';for(i=0;i<used;i++){if(!strcmp(userTable[i].userName,name))break;}if(i==used){cout<<"\n您输入的用户名不存在\n";//system("pause");return -1;}for(times=0;times<3;times++){memset(psw,'\0',sizeof(psw));cout<<"\n请输入密码:";for(i=0;c=getch();i++){if(c==13) break;elsepsw[i]=c;cout<<"*";}printf("\n");for(i=0;i<used;i++){if(!strcmp(psw,userTable[i].password)){printf("用户登录成功\n");//system("pause");break;}if(i==used){printf("您输入的密码错误,您还有%d次输入机会\n",2-times);if(times==2) exit(0);}else break;}return i;}//磁盘初始化void initDisk(){diskHead=(diskNode *)malloc(sizeof(diskNode));diskHead->maxlength=MaxDisk;diskHead->useFlag=0;diskHead->start=0;diskHead->next=NULL;}//分配磁盘int requestDist(int &startPostion,int maxLength){int flag=0; //标记是否分配成功diskNode *p,*q,*temp;p=diskHead;while(p){if(p->useFlag==0) //磁盘块未被使用,且剩余长度大于要创建文件的长度{startPostion=p->start;q=(diskNode *)malloc(sizeof(diskNode));q->start=p->start;q->maxlength=maxLength;q->useFlag=1;q->next=NULL;diskHead->start=p->start+maxLength;//剩余磁盘空间头指针后移diskHead->maxlength=p->maxlength-maxLength; //剩余磁盘空间长度减少flag=1;temp=p;if(diskHead->next==NULL) diskHead->next=q;else{while(temp->next) temp=temp->next;temp->next=q;}break;}p=p->next;}return flag;}//创建文件void createFile(char fileName[],int length){//int i,j;time_t rawtime;int startPos;UFD *fileNode,*p;for(p=userTable[userID].user->next;p!=NULL;p=p->next){if(!strcmp(p->file->fileName,fileName)){printf("文件重名,创建文件失败\n");//system("pause");return;}}if(requestDist(startPos,length)){fileNode=(UFD *)malloc(sizeof(UFD));fileNode->file=(fileTable *)malloc(sizeof(fileTable)); //这一步必不可少,因为fileNode里面的指针也需要申请地址,否则fileNode->file指向会出错strcpy(fileNode->file->fileName,fileName);fileNode->file->maxlength=length;fileNode->file->strat=startPos;fileNode->file->openFlag=false;time(&rawtime);//读取系统当前时间fileNode->file->timeinfo=localtime(&rawtime);fileNode->next=NULL;if(userTable[userID].user->next==NULL)//用户当前还没有创建文件时userTable[userID].user->next=fileNode;else //已创建过文件,找到最后一个的next 指针{p=userTable[userID].user->next;while(p->next) p=p->next;p->next=fileNode;}printf("创建文件成功\n");//system("pause");}else{printf("磁盘空间已满或所创建文件超出磁盘空闲容量,磁盘空间分配失败\n");//system("pause");}}//释放磁盘void freeDisk(int startPostion){diskNode *p;for(p=diskHead;p!=NULL;p=p->next){if(p->start==startPostion) //找到startPostion位置的指针break;}p->useFlag=false;}//查看文件void fileCat(char fileName[]){int startPos,length;int k=0;UFD *p,*q;q=userTable[userID].user;for(p=q->next;p!=NULL;p=p->next){if(!strcmp(p->file->fileName,fileName))break;}if(p){startPos=p->file->strat;length=p->file->length;p->file->openFlag=true; //文件打开标记printf("--------------------------------------------------------------\n");for(int i=startPos;k<length;i++,k++){if(i%50==0) printf("\n"); //一行大于50个字符换行printf("%c",disk[i]);}printf("\n\n----------------------------------------------------------\n");}else{printf("没有找到该文件,请检查输入的文件名是否正确\n");//system("pause");}}//覆盖写入void fileWrite(char fileName[]){UFD *p,*q;q=userTable[userID].user;int i,k,startPos;for(p=q->next;p!=NULL;p=p->next){if(!strcmp(p->file->fileName,fileName))break;}if(p){if(!strcmp(p->file->fileKind,"r")) //判断文件类型{printf("该文件是只读文件,写入失败\n");//system("pause");return;}char str[500];printf("please input content:\n");gets(str);startPos=p->file->strat;p->file->openFlag=true; //文件打开标记p->file->length=strlen(str);if(p->file->length>p->file->maxlength)printf("写入字符串长度大于该文件的总长度,写入失败\n");//system("pause");return;}for(i=startPos,k=0;k<(int)strlen(str);i++,k++)disk[i]=str[k];printf("文件写入成功\n");}else{printf("没有找到该文件,请检查输入的文件名是否正确\n");// system("pause");}if(p){p->file->openFlag=false;printf("%s文件已关闭\n",p->file->fileName);// system("pause");}}//重命名void fileRen(char fileName[],char name[]){UFD *p,*q;q=userTable[userID].user;for(p=q->next;p!=NULL;p=p->next){if(!strcmp(p->file->fileName,fileName))break;}if(p){while(q->next){if(!strcmp(q->next->file->fileName,name)){printf("您输入的文件名已存在,重命名失败\n");//system("pause");return;}q=q->next;strcpy(p->file->fileName,name);printf("重命名成功\n");//system("pause");}else{printf("没有找到该文件,请检查输入的文件名是否正确\n");//system("pause");}}//关闭文件void fileClose(char fileName[]){UFD *p,*q;q=userTable[userID].user;for(p=q->next;p!=NULL;p=p->next){if(!strcmp(p->file->fileName,fileName))break;}if(p){p->file->openFlag=false;printf("%s文件已关闭\n",p->file->fileName);//system("pause");}else{printf("没有找到该文件,请检查输入的文件名是否正确\n");//system("pause");}}//查看文件详细信息void fileLength(char fileName[]){int startPos,length;// char kind[3];int k=0;UFD *p,*q;q=userTable[userID].user;for(p=q->next;p!=NULL;p=p->next){if(!strcmp(p->file->fileName,fileName))break;}if(p){startPos=p->file->strat;length=p->file->length;//获取文件长度printf("文件长度为%d\n ",length);//system("pause");}else{printf("没有找到该文件,请检查输入的文件名是否正确\n");//system("pause");}}//检查文件是否关闭void ifClose(char fileName[]){bool open;UFD *p,*q;q=userTable[userID].user;for(p=q->next;p!=NULL;p=p->next){if(!strcmp(p->file->fileName,fileName))break;}if(p){open=p->file->openFlag;if(open==true)printf("%s文件未关闭\n",p->file->fileName);else //open=trueprintf("%s文件已关闭\n",p->file->fileName);//system("pause");}else{printf("没有找到该文件,请检查输入的文件名是否正确\n");//system("pause");}}void print(){ cout<<" create 创建文件\n";cout<<" length 查看文件长度\n";cout<<" cat 查看文件内容\n";cout<<" write 覆盖写入\n";cout<<" ren 重命名\n";cout<<" del 删除文件\n";cout<<" close 关闭文件\n";cout<<" return 退出用户,返回登录界面\n";cout<<" exit 退出程序\n";cout<<" ifclose 检查文件是否关闭\n";}//删除文件void delFile(char fileName[]){UFD *p,*q,*temp;q=userTable[userID].user;p=q->next;while(p){if(!strcmp(p->file->fileName,fileName)) break;//文件不存在else{p=p->next;q=q->next;}}if(p){if(p->file->openFlag!=true) //先判断是否有进程打开该文件,如果文件没被打开{temp=p;q->next=p->next;freeDisk(temp->file->strat); //磁盘空间回收free(temp);printf("文件删除成功\n");//system("pause");else{printf("该文件已被进程打开,删除失败\n");//文件被打开//system("pause");}}else{printf("没有找到该文件,请检查输入的文件名是否正确\n");//文件不存在//system("pause");}}int main(){char order[commandAmount][10];strcpy(order[0],"create");strcpy(order[1],"cat");strcpy(order[2],"write");strcpy(order[3],"ren");strcpy(order[4],"del");strcpy(order[5],"close");strcpy(order[6],"return");strcpy(order[7],"exit");strcpy(order[8],"awrite");strcpy(order[9],"length");strcpy(order[10],"ifclose");charcommand[50],command_str1[10],command_str2[10],command_str3[5];//,command_str4[3];int i,j,k;int length;initDisk(); //初始化磁盘for(i=0;i<MaxUser;i++) //初始化用户UFD目录文件的头指针{userTable[i].user=(UFD *)malloc(sizeof(UFD));userTable[i].user->next=NULL;}cout<<"----------------------------------------------------------\n";cout<<"请先进入用户管理\n\n";cout<<" Creat user 创建新用户请输入1\n";cout<<" login 用户登录请输入2\n";cout<<"----------------------------------------------------------\n\n";while(1){cout<<"Please choose the function key:>";int choice;scanf("%d",&choice);if(choice==1) userCreate();else if(choice==2){userID=login();print();}else printf("您的输入有误,请重新选择\n");while (userID!=-1){fflush(stdin);cout<<"please input your command:>";gets(command);int select;for(i=0;command[i]!=' '&&command[i]!='\0';i++) //command_str1字符串存储命令的操作类型command_str1[i]=command[i];k=i;command_str1[k]='\0';for(i=0;i<commandAmount;i++){if(!strcmp(command_str1,order[i])){select=i;break;}}if(i==commandAmount){cout<<"您输入的命令有误,请重新输入\n";continue;}for(i=k+1,k=0;command[i]!=' '&&command[i]!='\0';i++,k++) //commmand_str2字符串存储文件名或用户名command_str2[k]=command[i];command_str2[k]='\0';k=i;switch(select){case 0:for(i=k+1,k=0;command[i]!=' '&&command[i]!='\0';i++,k++)command_str3[k]=command[i];command_str3[k]='\0';j=1;length=0; //初始化文件长度for(i=strlen(command_str3)-1;i>=0;i--) //把字符串转换为十进制{length+=(command_str3[i]-48)*j;j*=10;}createFile(command_str2,length);break;case 1:fileCat(command_str2);break;case 2:fileWrite(command_str2);break;case 4:delFile(command_str2);break;case 5:fileClose(command_str2);break;case 6:UFD *p;for(p=userTable[userID].user->next;p!=NULL;p=p->next) //退出用户之前关闭所有打的文件if(p->file->openFlag)p->file->openFlag=false;system("cls");userID=-1;break;case 7:exit(0);break;case 8:fileLength(command_str2);break;}}}return 0;}五打印的程序运行时初值和运行结果1、初值2、运行过程与结果六、心得体会通过这次的操作系统的课程设计,在老师的细心指导和同学的积极讨论下,终于做出了模拟Linux二级文件系统,能够简单得实现目录的创建和删除,文件的建立和删除,文件的读写等这些基本操作,并且着重改编了拷贝、剪切和查询的功能,了解二级目录的有关内容,并且通过编写的模拟Lunix下的操作环境有了更进一步的了解。