《计算机操作系统》
题 目:专 业:班 级:姓 名:学 号:指导教师:时 间: 课程设计 二级文件系统 计算机科学与技术
2011.6.01---2011.6.10
2011年 6 月13日
一、实验内容
为Linux系统设计一个简单的二级文件系统。要求做到以下几点: 1.可以实现下列几条命令: login 用户登录 dir 列目录 create 创建文件 delete 删除文件 open 打开文件 close 关闭文件 read 读文件 write 写文件
2.列目录时要列出文件名,物理地址,保护码和文件长度 二、实验目的
通过一个简单多用户文件系统的设计,加深理解文件系统的内部功能及内部实现。 三、开发环境
Windows操作系统 Microsoft Visual C++
四、分析设计 实验原理
通过程序模拟Linux文件系统,用一个二进制文件(FileSystem.disk)来模拟磁盘.设计一个多用户的二级文件系经统、实现一般的创建文件、目录,删除文件、目录,切换目录,打开、关闭文件、读写文件等操作。
文件系统,包含格式化,显示文件(目录),创建文件等几个简单命令的实现,而且能完成超级块的读写,节点的读写等过程. 本文件系统采用两级目录,其中第一级对应于用户账号,第二级对应于用户账号下的文件。另外,为了简单本文件系统未考虑文件共享、文件系统安全以及管道文件与设备文件等特殊内容。
1.程序执行流程图:
选择程序 开始 初始化
创建目录、 文件 2.数据块的分配和回收
开始 结束 格式化 删除目录、文件 查看目录、文件 进入指定目录 返回上一查询 系统是否有空超级块中是否有空返回当前空闲块地址;超级块空闲指针开启新的块组,将其地址信息读入超级块;返回该块组首地址 结束
设计FileSystem类负责管理磁盘空间和磁盘内存I节点,负责对磁盘空间和磁盘数据进行优化管理。并提代接口言方法供用户或程序调用。
内存 磁盘 System 用户1用户2用户3用户n
五、 打印的源程序及附上的注释
#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 //登录 int login() { char name[10],psw[10]; char c; int i,times; cout<<\"请输入用户名:\"; for(i=0;c=getch();i++) { if(c==13) break; else name[i]=c; printf(\"%c\} name[i]='\\0'; for(i=0;i for(times=0;times<3;times++) { memset(psw,'\\0',sizeof(psw)); cout<<\"\\n请输入密码:\"; for(i=0;c=getch();i++) { if(c==13) break; else psw[i]=c; cout<<\"*\"; } printf(\"\\n\"); for(i=0;i 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 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\ // 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\ //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 \ //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\ else //open=true printf(\"%s文件已关闭\\n\ //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\"); char command[50],command_str1[10],command_str2[10],command_str3[5];//,command_str4[3]; int i,j,k; int length; initDisk(); //初始化磁盘 for(i=0;i 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\ 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 return 0; } 五 打印的程序运行时初值和运行结果 1、初值 2、运行过程与结果 六 、心得体会 通过这次的操作系统的课程设计,在老师的细心指导和同学的积极讨论下,终于做出了模拟Linux二级文件系统,能够简单得实现目录的创建和删除,文件的建立和删除,文件的读写等这些基本操作,并且着重改编了拷贝、剪切和查询的功能,了解二级目录的有关内容,并且通过编写的模拟Lunix下的操作环境有了更进一步的了解。通过本次试验,我收获颇多 ,也认识到了号多问题,通过与老师之间的交流,不断地思考问题,本次试验是自己独立完成的,遇到了许多困难,通过与老师和同学交流,学到了好多思考问题的方法。谢谢老师和同学们 因篇幅问题不能全部显示,请点此查看更多更全内容