生活随笔
收集整理的這篇文章主要介紹了
操作系统课程设计之二级文件系统演示
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
其實(shí),剛拿到這個(gè)題目時(shí),我真的沒有思路,隨后我就對著老師的課設(shè)指導(dǎo)書進(jìn)行研究,對二級文件系統(tǒng)的演示這個(gè)課題的每個(gè)要求進(jìn)行分析,總算是有了思路。下面給出我的分析。
文件系統(tǒng)演示
一、課程設(shè)計(jì)目的
使學(xué)生熟悉文件管理系統(tǒng)的設(shè)計(jì)方法;加深對所學(xué)各種文件操作的了解及其操作方法的特點(diǎn)。
//既然是基于控制臺的,我們可以更改顏色玩玩
二、課程設(shè)計(jì)內(nèi)容
設(shè)計(jì)一個(gè)簡單的多用戶文件系統(tǒng)。即 //和后面一樣,用結(jié)構(gòu)體數(shù)組實(shí)現(xiàn)
①在系統(tǒng)中用一個(gè)文件來模擬一個(gè)磁盤; //switch語句或者if-else語句實(shí)現(xiàn),既然這里說到了 用一個(gè)文件去模擬一個(gè)磁盤,換句話說,在你的課設(shè)里,必須要有磁盤空間分配的思路在里面,不然就不是模擬磁盤了。
②此系統(tǒng)至少有:Create、delete、open、close、read、write等和部分文件屬性的功能。
③實(shí)現(xiàn)這個(gè)文件系統(tǒng)。 //文件系統(tǒng)要實(shí)現(xiàn)
④能實(shí)際演示這個(gè)文件系統(tǒng)。//cmd演示即可
基本上是進(jìn)入一個(gè)界面(此界面就是該文件系統(tǒng)的界面)后,可以實(shí)現(xiàn)設(shè)計(jì)的操作要求。
三、課程設(shè)計(jì)指導(dǎo)
1)設(shè)計(jì)一個(gè)10個(gè)用戶的文件系統(tǒng),每次用戶可保存10個(gè)文件,一次運(yùn)行用戶可以打開5個(gè)文件。 //三個(gè)數(shù)組的大小分別為 10、10、5
//一次運(yùn)行用戶最多可以打開5個(gè)文件如何實(shí)現(xiàn)? 在用戶文件里面加變量判斷,用戶每打開一個(gè)就+1,
//每次用戶最多可保存10個(gè)文件如何實(shí)現(xiàn)? 很明顯,同時(shí)保存我們是無法做到的,無論是誰,都無法做到,也就是說還是一個(gè)個(gè)保存的,那么同樣可以設(shè)置變量判斷。如果保存的較多,那么只好請用戶單獨(dú)關(guān)閉某些指定的文件。
2)程序采用二級文件目錄(即設(shè)置主目錄MFD)和用戶文件目錄(UFD)。另外,為打開文件設(shè)置了運(yùn)行文件目錄(AFD)。 //存放各個(gè)用戶目錄的文件夾、用戶目錄
//是說運(yùn)行的所有文件用一個(gè)目錄層次表示嗎
3)為了便于實(shí)現(xiàn),對文件的讀寫作了簡化,在執(zhí)行讀寫命令時(shí),只需改讀寫指針,并不進(jìn)行實(shí)際的讀寫操作。 //整型的變量判斷是否讀寫完成了 下面的pointer
4)因系統(tǒng)小,文件目錄的檢索使用了簡單的線性搜索。 //鏈表的順序查找
5)文件保護(hù)簡單使用了三位保護(hù)碼:允許讀寫執(zhí)行、對應(yīng)位為 1,對應(yīng)位為0,則表示不允許讀寫、執(zhí)行。 //標(biāo)記變量即可實(shí)現(xiàn)
6)程序中使用的主要設(shè)計(jì)結(jié)構(gòu)如下:主文件目錄和用戶文件目錄(MFD、UFD),打開文件目錄(AFD)即運(yùn)行文件目錄,如圖5.1所示。//主要的結(jié)構(gòu)體設(shè)計(jì)
還有MFD、UFD、AFD最好全部存到文件里面去,不然每次都要輸入,十分麻煩,而且不能通過看文件 查看到自己的實(shí)驗(yàn)現(xiàn)象,著實(shí)不便。
參考的數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)如下
struct TYPE_UFD //用戶文件目錄
{
string File_Name; //文件名
bool Read; //讀保護(hù)碼,true為可讀
bool Write; //寫保護(hù)碼,true為可寫
bool Execute; //執(zhí)行保護(hù)碼,true為可執(zhí)行
int Length_File; //文件長度
}; //用戶文件目錄和用戶打開的文件目錄是不是都各有自己的屬性
struct TYPE_MFD //主文件目錄
{
string User_Name; //用戶名
TYPE_UFD *Pointer; //用戶文件目錄指針
};
//很明顯,第三個(gè)結(jié)構(gòu)體沒有指針域,但我們是需要指針域的,還有下面紅色部分可以合在一個(gè)整型變量里面的
struct TYPE_AFD //打開文件目錄
{
int File_ID; //打開的文件號
boolRead;//讀保護(hù)碼,true為可讀
boolWrite;//寫保護(hù)碼,true為可寫
boolExecute;//執(zhí)行保護(hù)碼,true為可執(zhí)行
int Pointer; //讀寫指針
};
7)文件系統(tǒng)結(jié)構(gòu)如圖5.2所示
//很明顯,這里要用到的數(shù)據(jù)結(jié)構(gòu)是 鏈表
? ??
8)文件系統(tǒng)算法的流程圖如圖5.3所示。
? ? ? ? ? ? ? ? ? ? ? ? ? ??
圖5.3文件系統(tǒng)算法的流程圖
//這里告訴了你 main函數(shù)的主要調(diào)用的函數(shù)順序
9)注意對于物理塊的訪問(包括訪問指針,空閑位)需要經(jīng)過輸入輸出,相當(dāng)于通過定位對文件進(jìn)行讀寫。打開文件目錄(AFD)是在內(nèi)存中,由打開文件時(shí)創(chuàng)建。
好了,分析完了,就要開始編寫代碼了,下面附上我小小的代碼,還有很多需要修改的地方,做的不好的地方,大神就請?jiān)?#xff0c;也希望多多指點(diǎn)我。
先附上效果圖:
? ? ? ? ? ? ? ??
頭文件部分:
#include<cmath>
#include<ctime>
#include<string>
#include<conio.h>
#include<fstream>
#include<cstdlib>
#include<iostream>
#include<windows.h>
using namespace std;typedef struct UFD
{string File_name; //文件名int Start; //文件在磁盤存儲空間的起始地址int Protect; //文件的屬性int File_length; //文件的長度int Max_File_length; //文件的最大長度struct UFD *next;
}UFD,*UFD_ptr;typedef struct MFD
{string User_name;string User_passwd;UFD *Ufd_next;int End;struct MFD *next;
}MFD,*MFD_ptr;typedef struct AFD
{string File_name;int File_length;int Start;int Protect;int Pointer; //根據(jù)這個(gè)指針的值去完成用戶的要求 讀寫指針int Max_File_length;struct AFD *next;
}AFD,*AFD_ptr;
源文件部分:
#include"os_fss.h"#define MaxDisk 512*1024 //一個(gè)扇區(qū)512字節(jié),假設(shè)有1024個(gè)扇區(qū),模擬磁盤的大小
int Max_User=10;
int Max_Open=5;
int Max_End=0;
UFD_ptr pufd=NULL;
MFD_ptr pmfd=NULL;
AFD_ptr pafd=NULL;
char User_name[30]; //存放當(dāng)前用戶的用戶名
char flag='n';
char Disk_Size[MaxDisk]; //最后在打印輸出的時(shí)候,用RWX表示即可typedef struct Disk_Table
{int Max_length; //最大長度int Start; //開始位置
}Disk_Node;
Disk_Node Disk_Head;void Init_Disk()
{Disk_Head.Max_length=MaxDisk;Disk_Head.Start=0;
}bool Init_MFD()
{pmfd=(MFD *)new MFD; //帶頭節(jié)點(diǎn)的單向鏈表MFD *p=pmfd;ifstream ifs("MFD.txt"); //文件的輸入流對象if(!ifs){cerr<<"錯(cuò)誤:無法打開文件"<<endl;p->next=NULL;p->Ufd_next=NULL;return false;}while(!ifs.eof()){p->next=(MFD *)new MFD;ifs>>p->next->User_name>>p->next->User_passwd>>p->next->End; if(p->next->End>Max_End)Max_End=p->next->End;p=p->next;p->Ufd_next=NULL;p->next=NULL;}ifs.close();return true;
}void Print_UFD()
{UFD *p=pufd->next; if(!p){cout<<"抱歉,該用戶沒有創(chuàng)建任何文件,請先創(chuàng)建!!!"<<endl;return ;}cout<<"文件名\t\t最大文件長度\t文件權(quán)限\t起始位置\t文件長度"<<endl;while(p){cout<<p->File_name<<"\t\t"<<p->Max_File_length;if(p->Protect==0)cout<<"\t\t"<<"---";else if(p->Protect==1)cout<<"\t\t"<<"r-x";else if(p->Protect==2)cout<<"\t\t"<<"rwx";cout<<"\t\t"<<p->Start;cout<<"\t\t"<<p->File_length<<endl;p=p->next;}
}bool Init_UFD(char *name)
{ifstream ifs(name); pufd=(UFD *)new UFD;UFD *p=pufd;char temp[MaxDisk];bool Index=false;if(!ifs){cerr<<"錯(cuò)誤:無法打開文件"<<endl;p->next=NULL;return false;}while(!ifs.eof()){memset(temp,'\0',sizeof(temp));p->next=(UFD *)new UFD;if(!Index){ pmfd->Ufd_next=p->next;Index=true;}ifs>>p->next->File_name>>p->next->Max_File_length>>p->next->Protect>>p->next->Start>>p->next->File_length;ifs>>temp;if(temp[0]=='#')temp[0]='\0';for(int i=p->next->Start,j=1;j<=p->next->Max_File_length-1;i++,j++){Disk_Size[i]=temp[j-1];if(!Disk_Size[i])break;}Disk_Head.Max_length-=p->next->Max_File_length;// Disk_Head.Start+=p->next->Max_File_length;p=p->next;p->next=NULL;}ifs.close(); return true;
}void Rename_File()
{string File_name;UFD *temp=pufd;char Index;
SD:cout<<"請輸入文件的名字:"<<endl;cin>>File_name;while(temp){if(temp->File_name==File_name){cout<<"請輸入新的文件名:"<<endl;cin>>File_name;temp->File_name=File_name;break;}temp=temp->next;}if(!temp){cout<<"抱歉,輸入的文件不存在,無法完成重命名文件操作,是否繼續(xù)操作<y/n>?"<<endl;cin>>Index;if(Index=='y')goto SD;elsereturn ;}elsecout<<"修改成功!!!"<<endl;
}bool User_Check()
{string User_passwd;int Count=0;while(1){cout<<"請輸入用戶名:";cin>>User_name;
INIT:cout<<"請輸入密碼:";cin>>User_passwd;MFD *p=pmfd->next;char temp[30];memset(temp,'\0',sizeof(temp));strcpy(temp,User_name);Count++;while(p){if(User_name==p->User_name){if(User_passwd==p->User_passwd)cout<<"登入成功."<<endl;else{cout<<"抱歉,密碼錯(cuò)誤,登陸失敗,請重新輸入!!!"<<endl;if(Count==3){cout<<"密碼錯(cuò)誤次數(shù)過多,系統(tǒng)運(yùn)行結(jié)束!!!"<<endl;return false;}goto INIT;}strcat(temp,".txt"); Init_UFD(temp);// Print_UFD();Disk_Head.Start=Max_End;return true;}p=p->next;}cout<<"用戶名不存在,請重新輸入!!!"<<endl;}
// return false;
} void Init_AFD()
{pafd=(AFD *)new AFD;pafd->next=NULL;
}bool Create_MFD()//創(chuàng)建文件命令
{string User_name;char User_passwd[30];MFD *p = pmfd;cout<<"請輸入要創(chuàng)建的用戶名: ";cin>>User_name;cout<<"請輸入"<<User_name<<"用戶的密碼:(默認(rèn)為:admin)";getchar();cin.getline(User_passwd,30);if(User_passwd[0]=='\0')strcpy(User_passwd,"admin");while(p){if(User_name==p->User_name){cout<<"此用戶名已存在!!!"<<endl;return false;}if(!p->next)break;p= p->next;}p->next = (MFD *)new MFD; //尾插法p=p->next;p->User_name=User_name;p->User_passwd=User_passwd;p->End=0;p->next = NULL;p->Ufd_next = NULL;Max_User--;return true;
} //應(yīng)該是 不同的用戶下的UFD文件名是不一樣的啊,怎么出問題了bool Create_UFD()//創(chuàng)建文件命令
{string File_name;UFD *p = pufd;unsigned int Protect;int Max_File_length;
// AFD *pa = pafd;cout<<"請輸入要創(chuàng)建的文件名: ";cin>>File_name;cout<<"請輸入要創(chuàng)建的文件保護(hù)類型:";cin>>Protect;cout<<"請輸入文件的最大容量:"<<endl;cin>>Max_File_length;while(p){if(File_name==p->File_name){cout<<"此文件名已存在!!!"<<endl;return false;}if(!p->next)break;p= p->next;}p->next = (UFD *)new UFD; //尾插法p=p->next;p->File_name=File_name;p->Max_File_length=Max_File_length;p->Start=Disk_Head.Start;p->Protect = Protect;
// p->Time_info= //暫定p->File_length = 0; //剛創(chuàng)建文件時(shí),文件是空的Disk_Head.Start+=Max_File_length;p->next = NULL; //我覺得這部分代碼有問題;用戶創(chuàng)建了一個(gè)文件并不代表該文件就被打開了return true;
}bool Delete_UFD() //關(guān)于主目錄的用戶文件夾的文件刪除-->先這樣寫,好吧 //如果文件已經(jīng)打開了,是不能刪除的
{string File_name;cout<<"請輸入要刪除的文件名:";cin>>File_name;UFD *p=pufd,*temp;AFD *pa=pafd;while(pa->next){if(File_name==pa->next->File_name){cout<<"抱歉,該文件已被打開,請先關(guān)閉,再進(jìn)行刪除操作!!!"<<endl;return false;}}while(p->next){if(File_name==p->next->File_name){temp=p->next;p->next=p->next->next; //如果說要回收模擬的磁盤空間的話,應(yīng)該是回收最大長度// Disk_Head.Max_length+=temp->Max_File_length; //鏈表中刪除了,其他的文件內(nèi)容的起始位置不變即可,又沒事,還是照樣可以訪問數(shù)據(jù)的嘛delete temp;cout<<"文件刪除成功!!!"<<endl;return true;}p=p->next;}cout<<"抱歉,要刪除的文件不存在!!!"<<endl;return false;
}bool Open()
{string File_name;unsigned int Protect;cout<<"請輸入要打開的文件名:";cin>>File_name;UFD *p=pufd->next;AFD *pa=pafd->next;while(pa){if(File_name==pa->File_name){cout<<"文件"<<File_name<<"已經(jīng)打開!!!"<<endl;return true;}if(!pa->next)break;pa=pa->next;}if(!pa) //如果找不到,或者打開的文件目錄鏈表為空表pa=pafd;while(p){if(File_name==p->File_name){if(!Max_Open){cout<<"抱歉,最多只能打開5個(gè)文件,請先關(guān)閉其他打開的文件再操作!!!"<<endl;return false;}if(p->Protect==0){cout<<"抱歉,此文件不可執(zhí)行任何操作!!!"<<endl;return false;}cout<<"請選擇以什么樣的方式打開文件<1-只讀,2-可讀可寫>:";cin>>Protect;pa->next=(AFD *)new AFD;pa=pa->next;pa->File_name=p->File_name;pa->Start=p->Start;pa->File_length=p->File_length;pa->Max_File_length=p->Max_File_length;pa->Protect=Protect;if(Protect==1)pa->Pointer=0; //Poniter取0表示此時(shí)用戶無法寫數(shù)據(jù)(沒有空間的含義)elsepa->Pointer=p->File_length;pa->next=NULL;Max_Open--;cout<<"文件"<<File_name<<"已經(jīng)打開!!!"<<endl;return true;}p=p->next;}cout<<"抱歉,要打開的文件不存在!!!"<<endl;return false;
}void Close()
{string file_name;UFD *pu=pufd->next;cout<<"請輸入要關(guān)閉的文件名:";cin>>file_name;AFD *p=pafd,*temp;while(p&&p->next){if(file_name==p->next->File_name){temp=p->next;p->next=p->next->next;if(temp->Protect==2) //可寫的文件才有權(quán)把新寫入的數(shù)據(jù)也保存起來嘛{while(pu){if(temp->File_name==pu->File_name){pu->File_length=temp->Pointer;break;}pu=pu->next;}}delete temp;cout<<"文件"<<file_name<<"關(guān)閉成功!!!"<<endl;return ;}p=p->next;}cout<<"抱歉,要關(guān)閉的文件沒有被打開!!!"<<endl;
}bool Read_File() //因?yàn)樽x寫都是通過修改運(yùn)行文件目錄的Pointer去模擬的嘛
{string File_name; //你要讀文件的話,你這文件肯定得在運(yùn)行/打開文件目錄里面,是吧unsigned int length;AFD *p=pafd->next;cout<<"請輸入要讀的文件名:";cin>>File_name;cout<<"請輸入要讀取的長度:"; //讀取的話,實(shí)際中文件的長度并不會改變cin>>length; //即讀取的長度并不能保存回去,為了方便(如果用戶是讀數(shù)據(jù)的話,pointer始終不變)while(p){if(File_name==p->File_name){for(int i=p->Start,j=1;j<=length;i++,j++)cout<<Disk_Size[i];cout<<endl;cout<<"文件"<<File_name<<"讀取成功!!!"<<endl;return true;}p=p->next;}cout<<"讀取失敗,文件沒有打開過!!!"<<endl;return false;
}bool Write_File() //寫的話,自然是運(yùn)行文件目錄
{string File_name;unsigned int length;AFD *p=pafd->next;char temp[MaxDisk]={'\0'};cout<<"請輸入要寫的文件名:";cin>>File_name;while(p){if(File_name==p->File_name){if(p->Protect!=2){cout<<"文件"<<File_name<<"不可寫"<<endl;return false;}cout<<"請輸入要寫入的長度:"<<endl;cin>>length;if(p->Pointer+length<=p->Max_File_length){cout<<"請寫入指定長度的內(nèi)容:<以回車作為結(jié)束符>"<<endl;getchar();gets(temp);for(int i=p->Start+p->File_length,j=1;j<=strlen(temp);i++,j++)Disk_Size[i]=temp[j-1];p->Pointer += length;cout<<"文件"<<File_name<<"寫入成功!!!"<<endl;}else{cout<<"欲寫入的數(shù)據(jù)大小發(fā)生溢出,已超過文件的分配容量,寫入失敗!!!"<<endl;return false;}return true;}p=p->next;}cout<<"寫入失敗,文件沒有打開過!!!"<<endl;return false;
}void Destroy_Space()
{MFD *pm=pmfd;while(pm){pmfd=pmfd->next;delete pm;pm=pmfd;}AFD *pa=pafd;while(pa){pafd=pafd->next;delete pa;pa=pafd;}UFD *pu=pufd;while(pu){pufd=pufd->next;delete pu;pu=pufd;}
}void Save_MFD()
{ofstream ofs; //文件的輸出流對象ofs.open("MFD.txt");if(!ofs.is_open()){cout<<"The MFD can't open!!!"<<endl;if(flag=='y')cout<<"正在保存主目錄用戶名信息..."<<endl;elseofs.close(); //該語句待定}MFD *p=pmfd->next;while(p){if(p->User_name==User_name)p->End=Disk_Head.Start;ofs<<p->User_name<<" "<<p->User_passwd<<" "<<p->End;if(p->next)ofs<<"\n"; p=p->next;}ofs.close();
}void Save_UFD(char *name)
{ofstream ofs; //文件的輸出流對象char temp[MaxDisk]={'\0'};ofs.open(name);if(!ofs.is_open()){cout<<"The "<<name<<"文件 can't open!!!"<<endl;ofs.close(); //該語句待定,這語句真的用的很妙,因?yàn)槲也]有馬上退出這次函數(shù)調(diào)用了}UFD *p=pufd->next;while(p){memset(temp,'\0',sizeof(temp));for(int i=p->Start,j=1;j<=p->Max_File_length;i++,j++){if(Disk_Size[i])temp[j-1]=Disk_Size[i];elsebreak;}if(!temp[0]) //如果文件沒有數(shù)據(jù)的話,就用空格表示此文件沒有任何內(nèi)容temp[0]='#'; ofs<<p->File_name<<" "<<p->Max_File_length<<" "<<p->Protect<<" "<<p->Start<<" "<<p->File_length<<" "<<temp;if(p->next)ofs<<"\n";p=p->next;}ofs.close();
}void Quit_System()
{AFD *pa=pafd->next;UFD *pu=pufd->next;while(pa){if(pa->Protect==2) //2表示可寫 //1表示只讀 //0表示不可操作{while(pu){if(pa->File_name==pu->File_name){pu->File_length=pa->Pointer;break;}pu=pu->next;}}pa=pa->next;}char temp[30];strcpy(temp,User_name);strcat(temp,".txt");Save_MFD();Save_UFD(temp);Print_UFD();Destroy_Space();
}void Print_Help()
{system("color 0b");cout<<"************************二級文件系統(tǒng)演示*************************"<<endl;cout<<"*\t\t命令 說明 *"<<endl; cout<<"*\t\tlogin 登錄系統(tǒng) *"<<endl; cout<<"*\t\tcreate 創(chuàng)建文件 *"<<endl; cout<<"*\t\tdelete 刪除文件 *"<<endl; cout<<"*\t\topen 打開文件 *"<<endl; cout<<"*\t\tclose 關(guān)閉文件 *"<<endl; cout<<"*\t\tread 讀取文件 *"<<endl; cout<<"*\t\twrite 寫入文件 *"<<endl;cout<<"*\t\tls 顯示目錄 *"<<endl;cout<<"*\t\trename 重命文件 *"<<endl;cout<<"*\t\thelp 幫助菜單 *"<<endl;cout<<"*\t\tcls 清除屏幕 *"<<endl;cout<<"*\t\tlogout 切換用戶 *"<<endl;cout<<"*\t\tquit 退出系統(tǒng) *"<<endl; cout<<"*****************************************************************"<<endl;
}void System_Init()
{
Start:Print_Help();Init_Disk();if(!Init_MFD()){int num;cout<<"主目錄還未創(chuàng)建,是否創(chuàng)建<y/n>!!!"<<endl;cin>>flag;cout<<"請輸入欲創(chuàng)建的用戶文件夾的個(gè)數(shù)(1-10):"<<endl;cin>>num;if(flag=='y'){while(num--){Create_MFD();if(!Max_User){ cout<<"本系統(tǒng),最多支持10個(gè)用戶,創(chuàng)建多余用戶失敗,請刪除其他用戶,再做嘗試!!!"<<endl;return ;}}Save_MFD();cout<<"主目錄已經(jīng)創(chuàng)建完成,用戶各自目錄已得到保存,是否繼續(xù)<y/n>!!!"<<endl;cin>>flag;if(flag=='y')goto Start;}}return ;
}void File_System()
{while(1){string Command;cout<<"請輸入命令:";cin>>Command;if(Command=="create")Create_UFD();else if(Command=="delete")Delete_UFD();else if(Command=="open")Open();else if(Command=="close")Close();else if(Command=="read")Read_File();else if(Command=="write")Write_File();else if(Command=="quit"){ Quit_System();break;}else if(Command=="ls")Print_UFD();else if(Command=="cls")system("cls");else if(Command=="login"){if(!User_Check())break;Init_AFD();}else if(Command=="rename")Rename_File();else if(Command=="logout"){cout<<"用戶登出成功!!!"<<endl;Quit_System();System_Init();File_System();}elsePrint_Help();}
}int main() //我保存,我不能連我的指針域也保存啊,這是不對的吧
{System_Init();File_System();return 0;
}
總結(jié)
以上是生活随笔為你收集整理的操作系统课程设计之二级文件系统演示的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。