OS6 文件管理
来源:互联网 发布:linux开机启动 编辑:程序博客网 时间:2024/06/07 21:45
OS6 文件管理
实验
采用二级文件目录结构,编写程序实现文件系统的文件存储空间的管理、文件的物理结构、目录结构管理和文件操作。
1、设计一个有m个用户的文件系统,每个用户最多可保存一个文件。
2、规定用户在一次运行中只能打开K个文件。
3、系统能检查键入命令的正确性,出错时应能显示出错原因。
4、对文件应能设置保护措施,如只能执行、允许读、允许写等。
5、对文件的操作设计提供一套文件操作:
CREATE建立文件;
DELETE删除文件;
OPEN打开文件;
CLOSE关闭文件;
READ读文件;
WRITE写文件。
6、二级目录结构如下图所示。主文件目录MFD
用户名 用户文件目录地址 user1 root1 … …用户文件目录UFD
文件名 状态(打开/建立 指针 file1 0 (FCB*)file … … …分析
为了简单实现,没有对目录进行更多的管理,每个用户仅一个根目录。- 数据结构
除以上的结构外,增加了:
PM 物理块的页面
FCB 文件控制块
- 数据结构
//简单模拟,不在添加TCB了//物理块const int MAX=4096;const int MAX_OPEN_FILE_USER=2;int page=16;char buf[MAX];//页式管理物理块,sys管理,仅此一份struct PM{ //指向物理块 int base; //这个长度都是一样的有系统决定 int len; //next为NULL表示文件结束 PM *next; bool status;//1 used 0 free};list<PM>pmFree;list<PM>pmUsed;struct FCB{ //文件名字 string name; //属性 0-r 1-w 2-e int attribute; //文件是否打开 int status;//文件新建状态可写入 --2 int len;//文件长度 //物理块位置 --指向页面 PM*next;};struct UFD{ //目录名字 string name; //1 打开 --没发现怎么用啊 -2代开失败 int status; int max_open_files; int num_open_files; //point to file list<FCB> file;};struct MFD{ string user; UFD ufd;};list<MFD>mfd;
算法:
底层的物理块管理
1、模拟程序申请了一块buf,物理块管理算法,便是对文件的数据存储具体位置的管理。
2、页式离散分区管理
listpmFree//空闲页面链表
listpmUsed//已分配页面链表
3、程序初始化完成对物理页面的分配
4、申请PM 从pmFree取一个PM,修改PM.status=1,从pmFree中删除,加入pmUsed
5、释放PM 修改PM.status=0,从pmUsed删除,加入pmFree。
当释放的物理块较多时,也可以先修改所有PM的status,然后使用PM同步。
6.PM同步:将pmUsed中status==0的PM删除,加入到pmFree中。文件操作
利用各种属性,对文件操作进行保护性操作。- CREATE
新建文件,填充FCB添加到UFD中,文件状态为2,新建状态的文件可读取写入,不文件读写权限限制。
第一次使用CLOSE命令后,status=0,此时文件将受文件读写权限控制。 - DELETE
删除文件,在检查权限,文件状态,正常后,主要是释放文件所占用的PM,这时的释放,可使用PM同步释放的方式。
最后讲文件的FCB从UFD中删除即可。 - OPEN
检查文件状态和限制后,status=1 - CLOSE
status=0 - WRITE
检查文件状态和属性,新建状态的可写入,未使用状态,检查文件属性r/e不可写。
关于写:讲要写入的数据一次,写入文件的PM中,PM不够则申请一个新的PM,链入上一个PM的next指针,
继续写入内容。为简单实现,程序只有追加写入一种,即只增加PM。 - READ
检查文件状态和属性,新建状态可读取,未使用装填,文件属性e不可读。
读:遍历文件的PM直到PM.next==NULL,每个PM读取位置由PM.base 和PM.len决定。
- CREATE
- 其他
实验中,遇到两个自己平常不注意的情况,
1.标准库中的list,在删除节点后继续迭代对出错,正确方式是,迭代器要赋值为删除节点函数的返回值,之
后便可继续迭代。
2.list的节点的指针返回,(TYPE*)(&(it->begin().firstvale));
3.case标签不能定义变量,解决加个花括号{},在这里边操作。 - code
#include<iostream>#include<list>using namespace std;//简单模拟,不在添加TCB了//物理块const int MAX=4096;const int MAX_OPEN_FILE_USER=2;int page=16;char buf[MAX];//页式管理物理块,sys管理,仅此一份struct PM{ //指向物理块 int base; //这个长度都是一样的有系统决定 int len; //next为NULL表示文件结束 PM *next; bool status;//1 used 0 free};list<PM>pmFree;list<PM>pmUsed;struct FCB{ //文件名字 string name; //属性 0-r 1-w 2-e int attribute; //文件是否打开 int status;//文件新建状态可写入 --2 int len;//文件长度 //物理块位置 --指向页面 PM*next;};struct UFD{ //目录名字 string name; //1 打开 --没发现怎么用啊 -2代开失败 int status; int max_open_files; int num_open_files; //point to file list<FCB> file;};struct MFD{ string user; UFD ufd;};list<MFD>mfd;void createUser(string name,string dir);void initSys();//分配物理块页面void initPM(int size=16);//模拟中目录只有一个//type:目录or 流文件 void create(string user,string file,int type,int attribute);void del(string user,string file);void open(string user,string file,int attribute);void close(string user,string file);void readfile(string user,string file);//直接覆盖void write(string user,string file,string in);void help();void readfile(string user,string file);void synFreePM();PM* getPM();FCB* getFile(string user,string name);UFD* getDIR(string user);void showFileContens(FCB*fcb);int main(){ initPM(); initSys(); string CMD[10]={"CREATE","DELETE","OPEN","CLOSE","READ","WRITE"}; int op=-1; string cmd,user,fileName; int fileType,attribute; while(true) { op=-1; cout<<"-----------input:USER CMD PARAMETERS ... /?(for cmd help)/EXIT"\ "------------"<<endl; cin>>cmd; cout<<cmd<<endl; if(cmd=="EXIT") break; else if(cmd=="?") { op=10; }else { for(int i=0;i<10;i++) { if(cmd==CMD[i]) { op=i; break; } } } switch(op) { case 0://CREATE cin>>user>>fileName>>fileType>>attribute; create(user,fileName,fileType,attribute); break; case 1://DELETE cin>>user>>fileName; del(user,fileName); break; case 2://OPEN cin>>user>>fileName>>attribute; open(user,fileName,attribute); break; case 3://CLOSE cin>>user>>fileName; close(user,fileName); break; case 4://READ cin>>user>>fileName; readfile(user,fileName); break; case 5://WRITE { //case 里边不能创建变量,可通过这样的方式解决 {} string tmp; cin>>user>>fileName>>tmp; cout<<user<<" "<<fileName<<" "<<tmp<<endl; write(user,fileName,tmp); break; } case 10: help(); break; default: cout<<"input wrong,no this cmd"<<endl; } cout<<endl; } return 0;}void createUser(string name,string dir){ MFD user; user.user=name; user.ufd.name=dir; user.ufd.status=0; user.ufd.max_open_files=MAX_OPEN_FILE_USER; user.ufd.num_open_files=0; mfd.push_back(user);}void initSys(){ int count=0; string user,dir; cout<<"创建用户数"<<endl; cin>>count; cout<<"用户名\t根目录"<<endl; for(int i=0;i<count;i++) { cin>>user>>dir; cout<<user<<"\t"<<dir<<endl; createUser(user,dir); }}//分配物理块页面void initPM(int size){ cout<<"初始化物理块页面,页面大小:"<<size<<endl; //每个块大小16 PM pm; pm.len=size; page=size; pm.base=0; pm.next=NULL; pm.status=0; int sum=MAX/16; for(int i=0;i<sum;i++) { pm.base=i*size; pmFree.push_back(pm); }}PM* getPM(){ cout<<"--------pm-----------"<<endl; PM *pm=NULL; if(pmFree.size()>0) { PM tmp=*(pmFree.begin()); tmp.status=1; cout<<"new applyed pm:"<<endl; cout<<tmp.base<<"-"<<tmp.len<<endl<<endl; pmFree.erase(pmFree.begin()); pmUsed.push_front(tmp); pm=(PM*)&(pmUsed.begin()->base); } if(pm==NULL) cout<<"apply dir error"<<endl<<endl; return pm;}void synFreePM(){ cout<<"---同步PM---"<<endl; list<PM>::iterator it=pmUsed.begin(); for(;it!=pmUsed.end();it++) { if(it->status==0) { pmFree.push_back(*it); it=pmUsed.erase(it);//注意这样更新it迭代器,否则会出错,具体原因查STL } }}UFD* getDIR(string user){ list<MFD>::iterator it; for(it=mfd.begin();it!=mfd.end();it++) { if(it->user==user) { return &(it->ufd); } } cout<<"apply dir error"<<endl; return NULL;}FCB* getFile(string user,string file){ UFD*ufd=getDIR(user); if(ufd==NULL) return NULL; list<FCB>::iterator it; for(it=ufd->file.begin();it!=ufd->file.end();it++) { if(it->name==file) { return (FCB*)&(it->name); } } cout<<"apply file error or file is creating which does not have file"<<endl; //返回NULL表示当前为空或者不存在该文件 return NULL;}void showFiles(){ cout<<endl<<"-----files-----"<<endl; list<MFD>::iterator it; for(it=mfd.begin();it!=mfd.end();it++) { cout<<it->user<<"\t"<<it->ufd.name<<"\t" <<"status:"<<it->ufd.file.size()<<endl; cout<<"files:"<<endl; if(it->ufd.file.size()==0) cout<<"no_files"<<endl; for(list<FCB>::iterator itf=it->ufd.file.begin(); itf!=it->ufd.file.end();itf++) cout<<itf->name<<endl; } cout<<endl;}void showFileContens(FCB*fcb){ cout<<endl<<"-----file_contents-----"<<endl; cout<<"file:"<<fcb->name<<" contents:"<<endl; PM*pm=fcb->next; int count=0; int lens=0; int size=fcb->len; for(int i=0,lens=0;i<fcb->len;i++,lens++) { if(pm==NULL) break; if(lens+1>=page) { pm=pm->next; lens=0; } cout<<buf[pm->base+lens]; count++; } cout<<endl; cout<<"file len:"<<fcb->len<<endl; cout<<"used pm count:"<<count<<endl<<endl;}//模拟中目录只有一个//type:目录or 流文件 void create(string user,string file,int type,int attribute){ cout<<"-------create-------"<<endl; PM *pm=getPM(); if(pm==NULL) return; UFD* ufd=getDIR(user); if(ufd==NULL) return; FCB*fcb=getFile(user,file); if(fcb!=NULL)//exits { cout<<file<<" already exits ->" <<"rename to "; file=file+"2"; cout<<file<<endl; } cout<<ufd->name<<endl; FCB nfcb; nfcb.name=file; nfcb.len=0; nfcb.attribute=attribute; nfcb.next=pm; //创建模式,表示此时可以对文件进行读写,而不管文件类型是否可写 nfcb.status=2; ufd->file.push_back(nfcb); pm->next==NULL; pm->status=1; showFiles();}void del(string user,string file){ cout<<"-------delete-------"<<endl; UFD *ufd=getDIR(user); if(ufd!=NULL) { list<FCB>::iterator it=ufd->file.begin(); for(;it!=ufd->file.end();it++) { if(it->name==file) { cout<<"find file:"<<it->name<<endl; if(it->status>0) { cout<<"delete error:"<<it->name<<" is using"<<endl; }else if(it->status==0) { PM*pm=it->next; while(pm!=NULL) { //统一更新删除,不在这一个一个的删 pm->status=0; pm=pm->next; } it->next=NULL; cout<<"deleted file:"<<it->name<<endl; ufd->file.erase(it); break; } } } } //同步PM list synFreePM(); showFiles();}void open(string user,string file,int attribute){ cout<<"-------open-------"<<endl; UFD *ufd=getDIR(user); if(ufd==NULL) return; if(ufd->num_open_files+1>ufd->max_open_files) { cout<<"the num of openned files limits in"<<ufd->max_open_files<<endl; return; } FCB*fcb=getFile(user,file); if(fcb==NULL) return; if(fcb->status!=0&&fcb->status!=2)//0can use 2 new create -2 not exists 1 used { cout<<"this file cant use:"<<fcb->status<<endl; return; } if(fcb->status==0) fcb->status=1; ufd->num_open_files++; cout<<"open the file:"<<fcb->name<<endl; showFiles();}void close(string user,string file){ cout<<"-------close-------"<<endl; cout<<file<<endl; FCB*fcb=getFile(user,file); if(fcb==NULL) return; fcb->status=0;//将刚创建的文件状态设为正常 UFD *ufd=getDIR(user); ufd->num_open_files--;}void readfile(string user,string file){ cout<<"-------read-------"<<endl; FCB*fcb=getFile(user,file); if(fcb==NULL) return; if(fcb->status!=1&&fcb->status!=2) { cout<<"file is not openned for read"<<endl; return; } if(fcb->attribute==2) { cout<<"error:"<<fcb->name<<" cannt be read" <<endl<<"its attribute:"<<fcb->attribute<<endl; return ; } showFileContens(fcb);}//仅追加模式void write(string user,string file,string in){ //不在对文件控制了 cout<<"-------write-------"<<endl; FCB*fcb=getFile(user,file); if(fcb==NULL) return; if(fcb->status!=1&&fcb->status!=2) { cout<<"file is not openned for write"<<endl; return; } if(fcb->attribute!=1) { cout<<"error:"<<fcb->name<<" cannt be writed" <<endl<<"its attribute:"<<fcb->attribute<<endl; return; } int size=in.length(); //create时,分配了一个PM,当时不在那操作就好了,全部交到write操作 PM*pm=fcb->next; int count=1; if(pm==NULL) cout<<"error:create 已经创建,但丢失"<<endl; while(pm->next!=NULL) { count++; pm=pm->next; } cout<<"last pm:"<<pm->base<<endl; cout<<"file len:"<<fcb->len<<endl; int begin=(count*page-fcb->len)%page;//page==pm->len cout<<"base:"<<begin<<endl; if(begin>=pm->len&&begin<0) { cout<<"error"<<endl; return; } for(int i=0;i<size;i++) { if(begin>=pm->len) { pm->next=getPM(); if(pm==NULL) return; pm=pm->next;//在这被坑了,只考虑链接,忘了更新指针 begin=0; } buf[pm->base+begin++]=in.at(i); fcb->len++; } showFileContens(fcb);}void help(){ cout<<"-------help-------"<<endl; cout<<"CREATE username filename filetype(file or dir) attribute(r/w/e) "<<endl; cout<<"DELETE username filename "<<endl; cout<<"OPEN username filename attribute"<<endl; cout<<"CLOSE username filename"<<endl; cout<<"WRITE username filename inputstring"<<endl; cout<<"READ username filename"<<endl;} ```- 测试数据```language3user1 root1user2 root2user3 root3? CREATE user1 test1 0 0CREATE user1 test1 0 0CREATE user1 test2 0 0CREATE user1 test3 0 0OPEN user1 test1 1OPEN user1 test2 2OPEN user1 test3 3 //测试一个用户最多打开k个文件OPEN user1 test12 2WRITE user1 test1 12345678901234567890 //测试写入READ user1 test1 //测试读取DELETE user1 test1CLOSE user1 test1DELETE user1 test1CREATE user2 test2 0 1 //测试多用户OPEN user2 test2 1WRITE user2 test2 aaaaabbbbbdddddfffffREAD user2 test2CLOSE user2 test2EXIT
- OS6 文件管理
- Cent-OS6.0安装eclipse(C++)
- OS6 新特性 UIRefreshControl 水滴效果
- linux (cent os6)php安装mcrypt
- win7 下安装 cent os6.3
- cent os6.5 阿里云服务器安装
- 文件管理
- 文件管理....
- 文件管理
- 文件管理
- 文件管理
- 文件管理
- 文件管理
- 文件管理
- 文件管理
- 文件管理
- 文件管理
- 文件管理
- 第十八周:( 期末机试模拟) 小黄车(c++)
- 删除C++ string中的所有空格------我爱用erase方法
- Python中的函数(一)
- PHP 程序员的技术成长规划
- Android 应用内存泄漏的定位、分析与解决策略
- OS6 文件管理
- Hibernate(一)HQL查询、原生sql查询
- 雾都的迷人
- Hibernate(二)HQL&SQL参数绑定、投影和分页以及命名查询
- 整理浏览器对网页的兼容性问题(一)——JS&DOM篇
- 细数site、收录、索引哪些误区
- Python的Object基类的__init__方法
- webrtc 视频通话质量的评价方法
- Spring定时任务的几种实现