[精华]模拟一个小型类UNIX文件系统
- 格式:doc
- 大小:27.00 KB
- 文档页数:11
/* user.h */pragma once#include<string>class user{public:char userName[10]; //用户名int userID; //用户IDint priority; //用户权限char password[10]; //密码int group; //用户组user();~user();};/* user.cpp */#include"user.h"user::user(){strcpy(userName,"");userID=-1;priority=1;strcpy(password,"");}user::~user(){}/* memory.h */pragma onceclass memory{public:char data[64];memory();~memory();};/* memory.cpp */#include"memory.h"memory::memory(){for(int i=0; i<64; i++)data[i]='\0';}memory::~memory(){}/* iNode.h */#pragma once#include<time.h>class iNode{public:int fileStyle; //文件类型0为目录文件,为正规文件int fileMod; //文件权限0为可读,为可写,为可读写,3为可读可执行,为可写可执行,为可读写可执行int fileAddress[13]; //文件存储的物理块int fileLength; //文件长度int fileAssociated; //关联文件数time_t modifyTime; //文件修改时间char fileOwner[10]; //文件拥有者int fileGroup; //文件所属组iNode();~iNode();};/* iNode.cpp */#include"iNode.h"#include<string>iNode::iNode(){fileStyle=-1; //-普通文件0;d目录文件1;b块设备文件2;c字符设备文件3;|链接文件fileMod=-1;for(int i=0; i<13; i++)fileAddress[i]=-1;fileLength=0;fileAssociated=0;time (&modifyTime);strcpy(fileOwner,"");fileGroup=0;;}iNode::~iNode(){}/* directory.h */#pragma onceclass directory{public:char fileName[256]; //文件名int directoryID; //文件i节点号int parentID; //文件父节点号directory();~directory();};/* directory.cpp */#include"directory.h"#include<string>directory::directory(){strcpy(fileName,"");directoryID=-1;parentID=-1;}directory::~directory(){}/*superBlock.h */#pragma onceclass superBlock{public:int bitMap[512]; //位示图,空闲,占用int freeBitNum; //空闲盘块数int freeINode[256]; //空闲节点superBlock();~superBlock();};/*superBlock.cpp */#include"superBlock.h"superBlock::superBlock(){int i;for( i=0; i<512; i++)bitMap[i]=0; //0时空闲,时占用for( i=0; i<256; i++)freeINode[i]=0; //0时空闲,时占用freeBitNum=512;}superBlock::~superBlock(){}/ fileOS.cpp : 定义控制台应用程序的入口点。
模拟一个简单二级文件管理系统设计目的:通过具体的文件存储空间的管理、文件的物理结构、目录结构和文件操作的实现,加深对文件系统内部功能和实现过程的理解。
设计内容:模拟一个简单二级文件管理系统一、实验内容描述1 实验目标本实验的目的是通过一个简单多用户文件系统的设计,加深理解文件系统的内部功能及内部实现.2 实验要求为DOS系统设计一个简单的二级文件系统.要求做到以下几点:①可以实现下列命令:login 用户登录dir 列文件目录create 创建文件delete 删除文件open 打开文件close 关闭文件read 读文件write 写文件②列目录时要列出文件名、物理地址、保护码和文件长度.③源文件可以进行读写保护.二、程序主要内容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,用户拥有的文件数组.代码:#include <stdio.h>#include <stdlib.h>#include <conio.h>#include <time.h>#include <string.h>#define MaxUser 100 //定义最大MDF主目录文件#define MaxDisk 512*1024 //模拟最大磁盘空间#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<MaxUser;i++) //初始化用户UFD目录文件的头指针{userTable[i].user=(UFD *)malloc(sizeof(UFD));userTable[i].user->next=NULL;}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,将文件a1的权限改为只读方式\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<MaxUser){printf("请输入用户名:");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)){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;elseuserTable[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;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){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;elsepsw[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",p->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",MaxDisk-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");}}运行结果视图:(略)。
摘要计算机发展到今天,从个人计算机到巨型计算机系统,毫无例外都配置一种或是多种操作系统。
操作系统管理和控制计算机系统中的所有硬、软件资源,合理地组织计算机工作流程,并且为用户提供一个良好的工作环境和友好的接口。
在计算机操作系统的功能中,对文件存储设备的管理是一项非常重要的任务,文件在存储器上按一定的顺序有组织地存放,使得用户访问高效,操作方便。
UNIX文件系统采用SFD和BFD方式管理文件:SFD称为符号文文件目录,存放文件名以及致使该文件说明信息表标识符ID;把存放文件说明信息和相应标识符的BFD称为i节点。
UNIX文件系统将存储设备分为引导块、超级快、i节点区、目录和数据区四个存储区。
引导块主要是为了存储引导系统启动的数据;超级块描述文件系统的状态,包括磁盘空闲块栈,空闲i结点栈;i节点区存放文件说明信息,每项32字节;目录和数据每个目录项16字节,文件名区分大小写。
在界面上我们使用MFC可视化设计,将实现的代码加载到MFC界面中,在响应鼠标消息的函数中调用实现模拟系统设计的代码,这样最后的操作是在Windows界面的操作,响应鼠标的命令。
界面美好,操作方便。
关键词:操作系统,文件系统,UNIX文件系统模拟摘要目录1. 概述 (6)2. 课程设计任务及要求 (6)2.1 设计任务 (6)2.2 设计要求 (7)3. 算法及数据结构 (7)3.1算法的总体思想(流程) (8)3.2 i节点模块 (8)3.2.1功能3.2.2 数据结构3.2.3算法3.3 装入和退出系统模块 (11)3.3.1功能3.3.2算法3.4用户登录注销模块 (14)3.4.1 功能3.4.2 数据结构及流程图3.4.3 算法3.5 目录管理模块 (16)3.5.1功能3.5.2 数据结构及流程图3.3.3算法3.6 创建删除文件模块 (19)3.6.1功能3.6.2 数据结构及流程图3.6.3算法3.7 文件模块 (21)3.7.1功能3.7.2 数据结构及流程图3.7.3算法4. 程序设计与实现 (24)4.1 程序流程图4.2 程序说明4.3 实验结果5. 结论 (28)6. 参考文献 (29)7. 收获、体会和建议 (29)1.概述UNIX文件系统采用SFD和BFD方式管理文件。
要求:模拟UNIX系统的空闲块成组链接法,实现磁盘存储空间的管理。
[提示]:(1)假定磁盘存储空间已被划分成长度为n的等长块,共有M块可供使用。
UNIX系统中采用空闲块成组链接的方法来管理磁盘存储空间,将磁盘中的每N个空闲块(N<M)分成一组,最后一组可以不足N块, 每组的第一块中登记了下一组空闲块的块数和块号,第一组的块数和块号登记在专用块中,登记的格式如下:当第一项内容为“0”寸,则第二项起指岀的空闲块是最后一组。
⑵现模拟UNIX系统的空闲块成组链接,假定共有8块可供使用,每3块为一组,则空闲块成组链接的初始状态为:开始时,空闲块号是顺序排列的,但经若干次的分配和归还操作后,空闲块的链接就未必按序排列了。
用二维数组A: array [0…M-1] of array [0 …n-1]来模拟管理磁盘空间,用A[i]表示第I块,第0块A[0]作为专用块。
(3) 成组链接的分组情况记录在磁盘物理块中,为了查找链接情况,必须把它们读入主存,故当磁盘初始化后,系统先将专用块内容复制到主存中。
定义一个数组MA存放专用块内容,即MA: =A[0]。
申请一块磁盘空间时,查MA从中找出空闲块号,当一组的空闲块只剩第一块时,则应把该块中指出的下一组的空闲块数和块号复制到专用块中,然后把该块分配给申请者。
当一组的空闲块分配完后则把专用块内容(下一组链接情况)复制到主存,再为申请者分配。
分配算法如下图。
采用成组链接的分配算法(4) 归还一块时给出归还的块号,若当前组不满规定块数时,将归还块登记入该组;若当前组已满,则另建一新组,这时归还块作为新一组的第一块,应把主存中登记的一组链接情况MA复制到归还块中,然后在MA重新登记一个新组归还一块的算法如下图。
采用成组链接的回收算法(5) 设计分配和归还磁盘空间的程序,能显示或打印分配的磁盘空间的块号,在完成一次分配或归还后能显示或打印各空闲块组的情况(各组的空闲块数和块号)。
模拟UNIX文件系统的设计及实现操作系统大作业UNIX文件系统是一种常见的操作系统文件系统,它提供了一种以层次结构组织文件和目录的方式来管理存储设备上的数据。
为了完成这个大作业,我们需要设计并实现一个简化版的UNIX文件系统,包括文件和目录的管理、文件的读写操作、文件权限的管理等。
首先,我们需要设计文件系统的存储结构。
文件系统可以在硬盘上以一个分区的形式存在,我们可以使用一个整数数组来表示硬盘,每个数组元素表示硬盘上的一个块。
我们还可以使用一个超级块来记录文件系统的信息,例如文件系统的状态、块的总数、块的使用情况等。
此外,我们还需要设计并实现一个索引节点表,用于保存文件或目录的元数据信息,例如文件的大小、权限、创建时间等。
接下来,我们需要实现文件和目录的管理功能。
文件和目录可以通过其在索引节点表中的索引来标识。
我们可以使用一个数组来表示目录,数组的每个元素都是一个目录项,记录了文件或子目录的名字和索引节点的索引。
我们还可以使用一个栈来保存当前目录的路径,方便用户在不同目录之间切换。
为了支持目录的嵌套,我们可以在目录项中添加一个指向父目录的索引。
在文件和目录的管理基础上,我们还需要实现文件的读写操作。
文件可以通过其索引节点的索引来标识。
当用户要读取文件时,我们需要根据文件的索引节点找到文件的块地址列表,然后将列表中的块读取到内存中。
当用户要写入文件时,我们需要找到文件的块地址列表中最后一个块,如果该块已满,则需要申请一个新的块,并将新块的地址添加到块地址列表中。
同时,我们还需要更新文件的大小和修改时间等元数据信息。
最后,我们还需要实现文件权限的管理功能。
文件的权限信息可以通过文件的索引节点来保存。
我们可以使用一个整数来表示文件的权限,例如八进制数,每一位代表一个权限,例如读取权限、写入权限和执行权限等。
当用户要访问文件时,我们需要根据用户的权限和文件的权限来判断用户是否具有相应的权限。
总结起来,要完成这个大作业,我们需要设计并实现一个模拟UNIX文件系统,包括文件和目录的管理、文件的读写操作、文件权限的管理等。
UNIX文件系统UNIX操作系统简介,讲稿,UNIX操作系统概述, UNIX操作系统UNIX是较早广泛使用的操作系统之一,它的第一版于1969年在Bell实验室产生,1975年对外公布,1976年以后在Bell实验室外广泛使用。
应用范围应用到几乎所有16位及以上的计算机上,包括微机、工作站、小型机、多处理机和大型机等等。
UNIX特点(1) 多任务、多用户(2) 并行处理能力(3) 管道(4) 安全保护机制(5) 功能强大的shell(6) 强大的网络支持(7) 系统源代码用C语言写成,移植性强(8) 出售源代码,软件厂家自己增删UNIX流派举例SCO UNIX PC兼容机Digital Unix Dec Alpha机Sun UNIX Sun工作站AIX IBM机, UNIX系统组成UNIX操作系统结构由三大部分组成:(1) kernel(内核)(2) shell(外壳)(3) 工具及应用程序1工具及应用程序shellkernel硬件UNIX Kernel 提供四个基本功能:进程、文件系统、通信、系统启动。
UNIX Shell 是UNIX的命令解释器,共有三种:(1) Bourne Shell sh(2) Korn Shell ksh(3) C-Shell csh一般系统默认为Bourne Shell, 本文以此shell为例。
, UNIX的几个名词用户名(user) UNIX是多用户操作系统,它允许多个用户同时使用。
每个用户拥有用户名、登录口令以及操作特权。
用户每次使用UNIX时必须先登录:输入用户名和口令。
一般用户的UNIX操作系统提示符一般为”$”。
工作组(group) 几个用户可以组成一组,同组内的用户可以共享信息。
root用户 UNIX的超级用户,拥有其他用户没有的特权。
root用户的UNIX操作系统提示符一般为”#”。
进程(process) 是正在执行的程序。
UNIX允许多个进程同时存在,每个进程都有唯一代号称为进程标识符(pid)。
问题描述]在任一OS下,建立一个大文件,把它假象成一张盘,在其中实现一个简单的模拟UNIX文件系统。
[基本要求]1.在现有机器硬盘上开辟20M的硬盘空间,作为设定的硬盘空间。
2.编写一管理程序对此空间进行管理,以模拟UNIX(linux)文件系统,具体要求如下:(1)要求盘块大小1k(2) i 结点文件类型正规文件目录文件(共1byte)块设备管道文件。
物理地址(索引表)共有13个表项,每表项2byte。
文件长度4byte。
联结计数1byte(3)0号块超级块栈长度50空闲盘块的管理:成组链接( UNIX)位示图法(Linux)(4)每建一个目录,分配4个物理块文件名14byte(5)目录项信息i 结点号2byte(6)结构:0#:超级块1#-20#号为i 结点区20#-30#号为根目录区(7)功能:1、初始化2、建立文件(需给出文件名,文件长度)3、建立子目录4、打开文件(显示文件所占的盘块)5、删除文件6、删除目录7、显示目录(即显示目录下的信息,包括文件、子目录等)8、显示整个系统信息2、模拟文件系统[问题描述]在任一OS下,建立一个大文件,把它假象成一张盘,在其中实现一个简单的小型文件系统。
[基本要求]该小型文件系统没有子目录机制,文件连续分配,不考虑分区。
做一个简单的操作界面,提供四条简单的命令:简单的ls、cat、cp、rd.进一步增强:上题中的文件系统功能:文件系统不连续分配,可以有子目录机制,(如两级子目录机制)。
附录课程设计报告内容一.实验题目与要求。
二.总的设计思想及环境说明、工具等。
三.本题所需数据结构与模块说明。
四.运行结果与运行情况。
五.自我评析与总结。
1.你认为你完成的哪些比较好或比较出色;2.差距与局限,什么做的不太好或什么地方可以做的更好以待改进;3.从本作业得到的收获:对编写与调试过程中经验教训的总结;4.完成本题的其他方法或你的设想;5.对本实验题的评价和改进意见。
如何编写一个简单的操作系统文件系统操作系统文件系统是操作系统管理存储设备上文件和目录的系统。
它的设计和实现对操作系统的性能和功能有着重要的影响。
一个好的文件系统需要具备高效的存储管理、可靠的数据存储和恢复机制、良好的用户接口等特点。
下面通过简单的文件系统设计来介绍文件系统的基本原理和实现步骤。
一、文件系统的基本要求1.存储管理:文件系统需要能够有效地管理存储设备上的存储空间,实现文件的分配和释放。
2.数据存储与恢复:文件系统需要具备数据持久化的能力,能够保证文件在存储设备上安全存储,并能够在系统崩溃时自动恢复数据。
3.文件操作接口:文件系统需要提供用户友好的文件操作接口,如读取、写入、创建、删除、重命名等操作。
二、文件系统设计1.文件控制块(FCB):文件系统中的每个文件都有对应的文件控制块,用来存储文件的基本信息,如文件名、大小、创建时间、修改时间、访问权限等。
2.目录结构:文件系统需要维护一个目录结构,用来记录文件和目录的层次关系。
可以采用树形结构来组织目录,每个目录节点包含文件或子目录的信息。
3.空闲块管理:文件系统需要通过空闲块管理来实现文件存储空间的分配和释放。
可以采用位图或空闲块链表的方式进行管理。
4.存储分配策略:文件系统需要设计合适的存储分配策略,如连续分配、链式分配、索引分配等。
不同的分配策略对文件系统的性能和可靠性有着重要影响。
5.数据恢复机制:文件系统需要设计合适的数据恢复机制来保证文件在系统崩溃时能够正确地恢复数据。
可以采用日志、备份、快照等方式来实现数据恢复。
6.用户接口:文件系统需要提供良好的用户接口,使用户能够方便地进行文件操作。
可以设计命令行或图形界面来实现用户与文件系统的交互。
三、文件系统实现步骤1.设计文件控制块结构:根据文件系统的需求,设计合适的文件控制块结构,包括文件名、文件大小、创建时间、修改时间、访问权限等字段。
2.设计目录结构:根据文件系统的需求,设计合适的目录结构,包括目录名称、父目录、子目录和文件的信息等字段。
[精华]模拟一个小型类UNIX文件系统题目一:模拟一个小型类UNIX文件系统一( 设计思想说明小型类UNIX文件系统是模拟UNIX中的文件系统,实现文件系统中一些基本的功能,即关于目录及文件的相关操作。
首先为这个文件系统申请1M的内存空间存放文件系统的空间结构。
编写的这个程序并不是通过读取文件获取信息的,故在程序结束之后先前修改过的数据并不保存。
空间结构包括引导块,专用块,i节点区,文件存储区,进程对换区。
由于课程设计的要求,对引导块和进程对换区不做要求,故在实现这个系统的过程中并没有对引导块和进程对换区进行设计。
专用块用来存放空闲块和i节点的资源管理表;i节点区用来存放i节点,包括文件的文件名,属性,占用内存大小,物理地址等信息;文件存储区用来存放文件的具体内容。
对于文件的打开,读,写,关闭等操作,程序设计了用户打开文件表和系统打开文件表以及内存活动i节点,为了更好地管理文件而设计的这两个表。
用户打开文件表使用一个结构体表示,它的指针指向对应的系统打开表的各项。
系统打开文件表同样使用一个结构体表示,它的指针指向内存活动i节点,共享计数等,简化以后留下内存活动i节点。
内存活动i节点是真正指向文件的具体内容,从而可以实现对文件的修改。
除了对文件进行的相关操作外,这个模拟系统还对目录进行了相关操作,系统使用树型目录结构,,故使用一个结构体表示,有目录的名字,父节点,子节点的主码,以及一些基本信息。
磁盘i节点的结构使指针指向文件的具体内容。
二( 相关数据结构的说明1. 描述用户的数据结构struct User //定义了一个用户,另外一个空间为新注册的用户使用{char username[15]; //用户名char passwd[15]; //用户密码 };struct User user[2];2. 描述目录的数据结构struct catalogue //存储目录的结构体 {char cataname[15]; //目录名int fathernum; //该目录的父节点int maxnum; //该目录最多可以拥有的子节点的个数int next[N]; //分别指向子节点 };struct catalogue Catalogue[M];3. 描述文件目录索引项的数据结构struct direntry //文件的目录索引项 {char filename[20]; //文件名struct direntry *before,*after; //它的前向指针和后向指针struct inode *filepointer; //指向i节点的指针char mode; //该文件所处的状态 };struct direntry *d_head;struct direntry *d_curr;描述i节点的数据结构 4.struct inode //i节点定义 {前向指针和后向指针 struct inode *before,*after; //int blocknum[5]; //存放文件的物理地址,该文件最大为5KBint uid; //创建该文件的用户主码int catnum; //文件所处目录的编码int sizenum; //文件所占内存块的大小int location; //文件所处位置 };struct inode *i_head;struct inode *i_curr;5. 描述系统打开表的数据结构struct listos //系统打开表 {struct direntry *list_os; //指向文件的目录项struct listos *after,*before; //前向指针和后向指针 };struct listos *lo_head;struct listos *lo_curr;6. 描述用户打开表的数据结构struct listfile //文件打开表 {struct listfile *before,*after; //前向指针和后向指针struct listos *list_file; //指向系统打开表项 };struct listfile *lf_head;struct listfile *lf_curr;7. 描述内存活动i节点的数据结构 struct memory //内存活动i节点 { struct inode *mem; //指向文件目录项struct memory *after; //后向指针 };struct memory *memhead;关于一些全局变量的定义 8.#define N 10 //每个目录最多拥有N个子目录#define M 30 //最多可拥有M个目录int I; //记录当前目录指针的位置int Inum; //记录当前已经拥有的目录数目int ID=0; //用户编号char choose[15]; //暂时存放操作指令int bitmap[1024]; //存放位示图char content[10000]; //暂时存放即将要写入文件的内容int FREENUM; //存放位示图为0的块号的开始char INODE[1024][1024]; //1M空间存放内容三( 各模块的算法流程图说明1. 用户登录模块的算法流程图开始登录L/l 其它选择L/R进入到操作模块输入用户名新密码和确认密码是否新密码和确认密码相等2. 操作模块的算法流程图开始cd open read write delete close logout mkdir dir 更打读写删关退创列改开文文除闭出建出件件当文文文系子目件件件统前目录目录下录的文件3. 更改当前目录的算法流程图开始cd输入想找的目录是否在目录链表中更改当前返回到操目录,修改作模块去全局变量4. 创建子目录的算法流程图开始mkdir输入想创建的目录名否是在目录链表中有重名更改当前目录,返回到操作模块去修改全局变量,将新的目录建立在原来的目录下的5. 列出目录中文件的相关信息的算法流程图开始dir输入想找的目录是否在目录链表中显示目录下的文返回到操件的信息,修改作模块去目录的全局变量6. 创建文件的算法流程图开始create输入要创建的文件名否是在文件目录索引链表中将新的文件存放在返回到操作模块去文件目录索引表中,并设置相关信息7. 打开文件的算法流程图开始open输入要打开的文件名在系统打开文是否件链表中&&当前用户创立该文件已经打是在文件目录开,不必再次索引表中打开将该文件插入否到系统打开文件表中想要操作的文件不存在8. 写文件的算法流程图开始write输入要进行写操作的文件名在系统打开文是否件链表中&&当前用户创立对该文件进行写操命令无效,作,并设置相关信息返回到操作模块去9. 读文件的算法流程图开始read输入要进行读操作的文件名在系统打开文是否件链表中&&当前用户创立对该文件的内容输命令无效,出以方便用户进行返回到操阅览作模块去10. 关闭文件的算法流程图开始close输入要关闭的文件名在系统打开文是否件链表中&&当前用户创立将文件的节点从系命令无效,统打开文件表中删返回到操除作模块去11. 删除文件的算法流程图开始delete输入要进行删除操作的文件名不在系统打开是否文件链表中&&当前用户创立命令无效,在文件目录返回到操索引链表中作模块去否该文件并不是存在,命令删除关于该节点的目无效录索引节点和i节点等相关信息四( 程序清单详见程序五( 使用说明书在运行程序之后,进入到模拟UNIX系统中,首先出现的提示是:用户登录还是要注册:L/l表示用户要登录,初始化的用户名:user1,密码:123;R/r表示要进行注册,在注册时要注意,输入的新密码和确认密码必须一致,否则程序将不进行这样的注册,在注册之后,程序自动为该用户登录。
但是在程序运行结束之后,注册的信息会被注销。
下次需要重新注册,注册的信息将不被保存。
这样登录和注册这部分的功能就实现了。
在正确登录之后,可以输入任意的命令进行想要的操作。
mkdir:创建新的子目录。
在输入这个命令之后,按Enter键,根据提示输入新目录的名称,形如“\root\home”,目录和目录之间使用\间隔。
一般情况下,以输入无重复的目录名为优先;如果要在不同的目录下建立同样名称的子目录,也是可以的。
在默认的情况下,是在当前目录下创建子目录,或者用户可以根据自己的需要,先更改当前目录,在进行子目录的的创建。
dir:显示当前目录下文件的相关信息,包括文件的名称,文件的物理地址以及文件的长度。
在输入这个命令之后,按Enter键,程序就将上述信息显示到屏幕上。
cd:修改当前目录。
输入这个命令之后,按Enter键,根据用户要修改的目录,输入修改后的目录,形如“\root\home”,目录和目录之间使用\间隔。
如果出现不同目录下的同名的子目录,如果用户没有指明,程序按照最先搜索到的目录对其进行确定,或者用户可以将父目录一同键入,以确定目录为用户需要的。
create:创建新的文件。
输入这个命令之后,键入Enter键,再输入新的文件名。
默认的情况下,将这个文件建立在当前目录下,如果要在其它的目录下创建,必须先通过cd命令修改当前目录,再建立新的文件,这样才能实现用户的需要。
open:打开文件命令。
输入这个命令之后,键入Enter键,再输入文件名。
如果该文件在文件目录索引表中不存在,则显示文件不存在。
如果在表中,且进行操作的用户的主码与建立该文件的用户的主码相同,则将该文件插入到系统打开文件表中。
且显示操作成功。
如果已经存在于系统打开表中,则显示已经存在于该表中。
write:写文件命令。
输入这个命令之后,键入Enter键,再输入文件名。
观察之后的提示,如果提示该文件不在系统打开文件表中,则不能进行该项操作。
如果在该表中,且用户主码符合要求,则提示请输入内容。
该程序的write命令只能将文件的内容进行重置。
read:读文件命令。
输入这个命令之后,键入Enter键,再输入文件名。
观察之后的提示,如果提示该文件不在系统打开文件表中,则不能进行该项操作。
如果在该表中,且用户主码符合要求,则输出该文件的内容。
close:关闭文件命令。
输入这个命令之后,键入Enter键,再输入文件名。
观察之后的提示,如果提示该文件不在系统打开文件表中,则不能进行该项操作。
如果在该表中,且用户主码符合要求,则关闭该文件,并且删除它在系统打开文件表中的节点。
delete:删除文件命令。
输入这个命令之后,键入Enter键,再输入文件名。
观察之后的提示,如果提示该文件在系统打开文件表中,则不能进行该项操作。