操作系统课程设计报告
姓 名: xxx ______ 学号: xxxxxxxxxxxx __ 专 业 年 级: 软件2班 指 导 教 师: __xx_
2016年 3月1日
1 概述
目的:本实验的目的是通过一个简单多用户文件系统的设计,加深理解文件系统的内部功能及内部实现.
意义: 本系统是基于linux平台运行在终端上的虚拟二级文件管理系统.模拟真正的文件管理系统,并采用用户登录机制对文件和文件夹进行创建,修改,删除的操作。对于文件夹而言,可以进行创建删除的操作;对于文件而言,可以创建,修改,删除.删除文件夹时,同时删除相应文件夹下的文件。采用用户登录使得用户管理文件更方便, 并形成了二级的文件管理模式。
主要任务:为DOS系统设计一个简单的二级文件系统。要求做到以下几点: ①可以实现下列命令: login 用户登录 dir 列文件目录 create 创建文件 delete 删除文件 open 打开文件 close 关闭文件 read 读文件 write 写文件
②列目录时要列出文件名、物理地址、保护码和文件长度。 ③源文件可以进行读写保护 2 系统设计 (1)设计思路
程序中要求每个用户在登陆后才可对其拥有的文件进行操作,用户对于其他用户的文件无操作权.文件操作包括浏览、创建、删除、打开、关闭、阅读、写入、修改模式。其他操作包括新建用户、帮助、用户登入、用户登出、退出系统.
在程序文件夹下有个名为“file”的系统根目录,此目录下包括:一个名为“mfd”的文件,记录所有注册过的帐号及密码;用户文件,以用户名作为
文件名,内容为其拥有的文件名及属性;一个名为“keiji\"的文件夹。“keiji”文件夹中包括:“file。p”指针文件,记录所有已用的物理地址;一些以物理地址为名的文件,内容为文件内容. (2) 数据结构
file结构体系统文件.数据结构:
fpaddrint,文件的物理地址、flengthint,文件长度、fmodeint,文件模式 0.只读;1。可写;2。可读写;3。保护、 fname[]char,文件名; filemode结构体文件状态数据结构:
isopenint,文件当前状态,0。关闭;1.打开、modeint,文件模式 0。只读;1。可写;2.可读写. (3)初始化
user结构体用户信息数据结构:
uname[]char,用户名、upassword[]char,用户密码; userfile结构体用户文件数据结构:
uname[]char,用户名、ufile[]file,用户拥有的文件数组 3 系统实现
#include #define MaxDisk 512*1024 // 模拟最大磁盘空间 512k #define commandAmount 12 // 对文件操作指令数 char disk[MaxDisk]; // 模拟512k磁盘空间 typedef struct distTable //磁盘块结构体 { int maxlength; int start; int useFlag; distTable *next; } diskNode; diskNode *diskHead; struct fileTable //文件块结构体 { char fileName[10]; int strat; //文件在磁盘存储空间的起始地址 int length; //文件内容长度 int maxlength; //文件的最大长度 char fileKind[3]; //文件的属性--读写方式 struct tm *timeinfo; bool openFlag; //判断是否有进程打开了文件 //fileTable *next; }; //两级目录结构体 typedef struct user_file_directory //用户文件目录文件UFD { //char fileName[10]; fileTable *file; user_file_directory *next; }UFD; //UFD *headFile; typedef struct master_file_directory //主文件目录 MFD { char userName[10]; char password[10]; UFD *user; }MFD; MFD userTable[MaxUser]; int used=0; //定义MFD目录中用已有的用户数 //文件管理 void fileCreate(char fileName[],int length,char fileKind[]); //创建文件 void fileWrite(char fileName[]); // 写文件 void fileCat(char fileName[]); //读文件 void fileRen(char fileName[],char rename[]); // 重命名文件 void fileFine(char fileName[]); //查询文件 void fileDir(char UserName[]); // 显示某一用户的所有文件 void fileClose(char fileName[]); // 关闭以打开的文件 void fileDel(char fileName[]); //删除文件 void chmod(char fileName[],char kind[]); //修改文件的读写方式 int requestDist(int &startPostion,int maxLength); //磁盘分配查询 void initDisk(); // 初始化磁盘 void freeDisk(int startPostion); //磁盘空间释放 void diskShow(); //显示磁盘使用情况 //用户管理 void userCreate(); int login(); int userID=-1; //用户登录的ID号,值为—1时表示没有用户登录 int main() { char order[commandAmount][10]; strcpy(order[0],”create”); strcpy(order[1],”rm”); strcpy(order[2],”cat”); strcpy(order[3],\"write”); strcpy(order[4],”fine\"); strcpy(order[5],\"chmod\"); strcpy(order[6],”ren”); strcpy(order[7],”dir\"); strcpy(order[8],\"close”); strcpy(order[9],”return”); strcpy(order[10],”exit”); strcpy(order[11],”df”); char command[50],command_str1[10],command_str2[10],command_str3[5],command_str4[3]; int i,k,j; int length; initDisk(); //初始化磁盘 for(i=0;i while(1) { printf(\"********************************************\\n”); printf(” 1、Creat user\\n”); printf(” 2、login\\n”); printf(”********************************** * * * * * *** * * \\n\" ) ; printf (\"Please chooce the function key:>\"); int choice; scanf(”%d\",&choice); if(choice==1) userCreate(); else if(choice==2) userID=login(); else printf(”您的输入错误!请重新选择\\n”); while(userID!=—1) { fflush(stdin); printf(”***********************************\\n\"); printf(” create—创建 格式:create a1 1000 rw,将创建名为a1,长度为1000字节可读可写的文件\\n\"); printf(\" rm-删除 格式:rm a1,将删除名为a1的文件\\n”); printf(\" cat-查看文件内容 格式:cat a1,显示a1的内容\\n”); printf(\" write-写入 格式:write a1\\n”); printf(\" fine-查询 格式:fine a1 ,将显示文件 a1的属性\\n”); printf(\" chmod—修改 格式:chmod a1 r,将文件al的权限改为只读方式\\n”); printf(” ren—重命名 格式:ren a1 b1 ,将a1改名为b1\\n”); printf(\" dir—显示文件 格式:dir aaa,将显示aaa用户的所有文件\\n\"); printf(\" df—显示磁盘空间使用情况 格式:df\\n\"); printf(\" close—关闭文件 格式:close a1,将关闭文件a1\\n\"); printf(” return-退出用户,返回登录界面\\n”); printf(” exit—退出程序\\n\"); printf(\"***********************************\\n”); printf(”please imput 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) { printf(”您输入的命令有误,请重新输入\\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]!=’ ';i++,k++) command_str3[k]=command[i]; command_str3[k]=’\\0’; k=i; j=1; length=0; //初始化文件长度 for(i=strlen(command_str3)—1;i>=0;i-—) //把字符串转换为十进制 { length+=(command_str3[i]—48)*j; j*=10; } for(i=k+1,k=0;command[i]!=' ’&&command[i]!=’\\0';i++,k++) command_str4[k]=command[i]; command_str4[k]=’\\0’; fileCreate(command_str2,length,command_str4);break; case 1:fileDel(command_str2);break; case 2:fileCat(command_str2);break; case 3:fileWrite(command_str2);break; case 4:fileFine(command_str2);break; case 5:for(i=k+1,k=0;command[i]!=' '&&command[i]!='\\0’;i++,k++) command_str3[k]=command[i]; command_str3[k]='\\0'; chmod(command_str2,command_str3);break; case 6:for(i=k+1,k=0;command[i]!='\\0’;i++,k++) command_str3[k]=command[i]; command_str3[k]='\\0’; fileRen(command_str2,command_str3);break; case 7:fileDir(command_str2);break; case 8:fileClose(command_str2);break; case 9: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 10:exit(0);break; case 11:diskShow();break; } } } return 0; } void userCreate() { char c; char userName[10]; int i; if(used for(i=0;c=getch();i++) { if(c==13) break; else userName[i]=c; printf(\"%c\; } userName[i]='\\0'; for(i=0;i〈used;i++) { if(!strcmp(userTable[i].userName,userName)) { printf(\"\\n”); printf(”该用户名已存在,创建用户失败\\n”); system(\"pause”); return; } } strcpy(userTable[used].userName,userName); printf(\"\\n”); printf(\"请输入密码:”); for(i=0;c=getch();i++) { if(c==13) break; else userTable[used]。password[i]=c; printf(”*”); } userTable[userID]。password[i]=’\\0’; printf(\"\\n”); printf(\"创建用户成功\\n\"); used++; system(\"pause\"); } else { printf(”创建用户失败,用户已达到上限\\n\"); system(”pause”); } fflush(stdin); } int login() { char name[10],psw[10]; char c; int i,times; printf(”请输入用户名:\"); for(i=0;c=getch();i++) { if(c==13) break; else name[i]=c; printf(”%c”,c); } name[i]='\\0'; for(i=0;i〈used;i++) { if(!strcmp(userTable[i]。userName,name)) break; } if(i==used) { printf(”\\n您输入的用户名不存在\\n”); system(”pause\"); return -1; } for(times=0;times<3;times++) { memset(psw,’\\0’,sizeof(psw)); printf(\"\\n请输入密码:\"); for(i=0;c=getch();i++) { if(c==13) break; else psw[i]=c; printf(”*”); } 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; } fflush(stdin); 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&&p—〉maxlength〉maxLength) { 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 fileCreate(char fileName[],int length,char fileKind[]) //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); strcpy(fileNode->file->fileKind,fileKind); 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 { 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) break; } p—〉useFlag=false; } void fileDel(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\"); } } 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”); printf(\"%s已被read进程打开,请用close命令将其关闭\\n”,p-〉file->fileName); system(\"pause\"); } 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(”文件写入成功,请用close命令将该文件关闭\\n”); system(”pause”); } else { printf(\"没有找到该文件,请检查输入的文件名是否正确\\n”); system(”pause\"); } } void fileFine(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) { printf(\"********************************** **********\\n”); printf(\"文件名:%s\\n\",p->file—>fileName); printf(”文件长度:%d\\n\—〉file—〉maxlength); printf(”文件在存储空间的起始地址:%d\\n\",p—〉file->strat); printf(\"文件类型:%s\\n”,p-〉file—>fileKind); printf(”创建时间:%s\\n”,asctime(p->file-〉timeinfo)); printf(\"********************************************\\n\"); system(”pause”); } else { printf(\"没有找到该文件,请检查输入的文件名是否正确\\n\"); system(”pause\"); } } void chmod(char fileName[],char kind[]) { 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) { strcpy(p—〉file—>fileKind,kind); printf(\"修改文件类型成功\\n\"); system(\"pause”); } else { printf(”没有找到该文件,请检查输入的文件名是否正确\\n\"); 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 fileDir(char userName[]) { UFD *p; int i,k; for(i=0;i〈MaxUser;i++) { if(!strcmp(userTable[i]。userName,userName)) { k=i;break; } } if(i==MaxUser) { printf(\"没有找到该用户,请检查输入用户名是否正确\\n\"); system(”pause”); return; } else { p=userTable[k].user->next; printf(\"********************************************************************************\\n\"); printf(”文件名 文件长度 文件在磁盘的起始地址 文件类型 创建时间\\n\"); for(;p!=NULL;p=p->next) printf(\"%s %d %d %s %s”,p->file—>fileName, p->file—>maxlength,p—〉file—>strat,p—〉file—〉fileKind,asctime (p—>file->timeinfo)); printf(”********************************************************************************\\n”); system(\"pause\"); } } void diskShow() { diskNode *p; int i=0,unusedDisk=0; printf(\"***************************************************************************\\n\"); printf(\" 盘块号 起始地址 容量(bit) 是否已被使用\\n”); for(p=diskHead;p!=NULL;p=p—〉next,i++) { if(p—〉useFlag==false) unusedDisk+=p-〉maxlength; printf(” %d %d %d %d \\n\",i,p—>start,p—〉maxlength,p—〉useFlag); } printf(\"***************************************************************************\\n”); printf(”磁盘空间总容:512*1024bit 已使用:%dbit 末使用:%dbit\\n\\n\—unusedDisk, unusedDisk); 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\"); } } 4 系统测试 系统功能测试、性能测试结果、结论 5 结论 1.链表初始化问题,采用单链表结构; 2。部分函数返回值弹出局部变量警告问题,解决办法是定义全局变量。 3。链表遍历不完整,新插入数据处理异常,解决办法是插入数据保存在文件前面,类似堆栈的设计. 4.局部变量过大导致堆栈溢出错误,使程序崩溃,解决办法是使用malloc()和free()函数动态分配和释放内存。 5。程序中初始化部分调用不完整,解决办法是改变就初始化一遍. 本次课程设计,使得没有接触过C语言的我得到了充分的锻炼.虽然接触过C++,但是使用起来才发现二者还是有很大区别的。在本次实践过程中,我也遇到了各种各样的问题,比如堆栈溢出等,通过上网查询以及翻阅相关书籍使得这些问题得以解决。虽然在课程设计前期对设计方案有初步的设计,但是在实践是才发现会出现很多不合理的地方,由此我真正认识到软件设计是非常重要的,最为软件开发人员,需要掌握的不仅仅是语言的实现,更要对前期的软件分析与设计多加掌握和了解。 因篇幅问题不能全部显示,请点此查看更多更全内容