生活随笔
收集整理的這篇文章主要介紹了
操作系统课程设计之二级文件系统演示
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
其實,剛拿到這個題目時,我真的沒有思路,隨后我就對著老師的課設指導書進行研究,對二級文件系統的演示這個課題的每個要求進行分析,總算是有了思路。下面給出我的分析。
文件系統演示
一、課程設計目的
使學生熟悉文件管理系統的設計方法;加深對所學各種文件操作的了解及其操作方法的特點。
//既然是基于控制臺的,我們可以更改顏色玩玩
二、課程設計內容
設計一個簡單的多用戶文件系統。即 //和后面一樣,用結構體數組實現
①在系統中用一個文件來模擬一個磁盤; //switch語句或者if-else語句實現,既然這里說到了 用一個文件去模擬一個磁盤,換句話說,在你的課設里,必須要有磁盤空間分配的思路在里面,不然就不是模擬磁盤了。
②此系統至少有:Create、delete、open、close、read、write等和部分文件屬性的功能。
③實現這個文件系統。 //文件系統要實現
④能實際演示這個文件系統。//cmd演示即可
基本上是進入一個界面(此界面就是該文件系統的界面)后,可以實現設計的操作要求。
三、課程設計指導
1)設計一個10個用戶的文件系統,每次用戶可保存10個文件,一次運行用戶可以打開5個文件。 //三個數組的大小分別為 10、10、5
//一次運行用戶最多可以打開5個文件如何實現? 在用戶文件里面加變量判斷,用戶每打開一個就+1,
//每次用戶最多可保存10個文件如何實現? 很明顯,同時保存我們是無法做到的,無論是誰,都無法做到,也就是說還是一個個保存的,那么同樣可以設置變量判斷。如果保存的較多,那么只好請用戶單獨關閉某些指定的文件。
2)程序采用二級文件目錄(即設置主目錄MFD)和用戶文件目錄(UFD)。另外,為打開文件設置了運行文件目錄(AFD)。 //存放各個用戶目錄的文件夾、用戶目錄
//是說運行的所有文件用一個目錄層次表示嗎
3)為了便于實現,對文件的讀寫作了簡化,在執行讀寫命令時,只需改讀寫指針,并不進行實際的讀寫操作。 //整型的變量判斷是否讀寫完成了 下面的pointer
4)因系統小,文件目錄的檢索使用了簡單的線性搜索。 //鏈表的順序查找
5)文件保護簡單使用了三位保護碼:允許讀寫執行、對應位為 1,對應位為0,則表示不允許讀寫、執行。 //標記變量即可實現
6)程序中使用的主要設計結構如下:主文件目錄和用戶文件目錄(MFD、UFD),打開文件目錄(AFD)即運行文件目錄,如圖5.1所示。//主要的結構體設計
還有MFD、UFD、AFD最好全部存到文件里面去,不然每次都要輸入,十分麻煩,而且不能通過看文件 查看到自己的實驗現象,著實不便。
參考的數據結構設計如下
struct TYPE_UFD //用戶文件目錄
{
string File_Name; //文件名
bool Read; //讀保護碼,true為可讀
bool Write; //寫保護碼,true為可寫
bool Execute; //執行保護碼,true為可執行
int Length_File; //文件長度
}; //用戶文件目錄和用戶打開的文件目錄是不是都各有自己的屬性
struct TYPE_MFD //主文件目錄
{
string User_Name; //用戶名
TYPE_UFD *Pointer; //用戶文件目錄指針
};
//很明顯,第三個結構體沒有指針域,但我們是需要指針域的,還有下面紅色部分可以合在一個整型變量里面的
struct TYPE_AFD //打開文件目錄
{
int File_ID; //打開的文件號
boolRead;//讀保護碼,true為可讀
boolWrite;//寫保護碼,true為可寫
boolExecute;//執行保護碼,true為可執行
int Pointer; //讀寫指針
};
7)文件系統結構如圖5.2所示
//很明顯,這里要用到的數據結構是 鏈表
? ??
8)文件系統算法的流程圖如圖5.3所示。
? ? ? ? ? ? ? ? ? ? ? ? ? ??
圖5.3文件系統算法的流程圖
//這里告訴了你 main函數的主要調用的函數順序
9)注意對于物理塊的訪問(包括訪問指針,空閑位)需要經過輸入輸出,相當于通過定位對文件進行讀寫。打開文件目錄(AFD)是在內存中,由打開文件時創建。
好了,分析完了,就要開始編寫代碼了,下面附上我小小的代碼,還有很多需要修改的地方,做的不好的地方,大神就請原諒,也希望多多指點我。
先附上效果圖:
? ? ? ? ? ? ? ??
頭文件部分:
#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; //根據這個指針的值去完成用戶的要求 讀寫指針int Max_File_length;struct AFD *next;
}AFD,*AFD_ptr;
源文件部分:
#include"os_fss.h"#define MaxDisk 512*1024 //一個扇區512字節,假設有1024個扇區,模擬磁盤的大小
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]; //存放當前用戶的用戶名
char flag='n';
char Disk_Size[MaxDisk]; //最后在打印輸出的時候,用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; //帶頭節點的單向鏈表MFD *p=pmfd;ifstream ifs("MFD.txt"); //文件的輸入流對象if(!ifs){cerr<<"錯誤:無法打開文件"<<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<<"抱歉,該用戶沒有創建任何文件,請先創建!!!"<<endl;return ;}cout<<"文件名\t\t最大文件長度\t文件權限\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<<"錯誤:無法打開文件"<<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<<"抱歉,輸入的文件不存在,無法完成重命名文件操作,是否繼續操作<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<<"抱歉,密碼錯誤,登陸失敗,請重新輸入!!!"<<endl;if(Count==3){cout<<"密碼錯誤次數過多,系統運行結束!!!"<<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()//創建文件命令
{string User_name;char User_passwd[30];MFD *p = pmfd;cout<<"請輸入要創建的用戶名: ";cin>>User_name;cout<<"請輸入"<<User_name<<"用戶的密碼:(默認為: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;
} //應該是 不同的用戶下的UFD文件名是不一樣的啊,怎么出問題了bool Create_UFD()//創建文件命令
{string File_name;UFD *p = pufd;unsigned int Protect;int Max_File_length;
// AFD *pa = pafd;cout<<"請輸入要創建的文件名: ";cin>>File_name;cout<<"請輸入要創建的文件保護類型:";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; //剛創建文件時,文件是空的Disk_Head.Start+=Max_File_length;p->next = NULL; //我覺得這部分代碼有問題;用戶創建了一個文件并不代表該文件就被打開了return true;
}bool Delete_UFD() //關于主目錄的用戶文件夾的文件刪除-->先這樣寫,好吧 //如果文件已經打開了,是不能刪除的
{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<<"抱歉,該文件已被打開,請先關閉,再進行刪除操作!!!"<<endl;return false;}}while(p->next){if(File_name==p->next->File_name){temp=p->next;p->next=p->next->next; //如果說要回收模擬的磁盤空間的話,應該是回收最大長度// Disk_Head.Max_length+=temp->Max_File_length; //鏈表中刪除了,其他的文件內容的起始位置不變即可,又沒事,還是照樣可以訪問數據的嘛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<<"已經打開!!!"<<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個文件,請先關閉其他打開的文件再操作!!!"<<endl;return false;}if(p->Protect==0){cout<<"抱歉,此文件不可執行任何操作!!!"<<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表示此時用戶無法寫數據(沒有空間的含義)elsepa->Pointer=p->File_length;pa->next=NULL;Max_Open--;cout<<"文件"<<File_name<<"已經打開!!!"<<endl;return true;}p=p->next;}cout<<"抱歉,要打開的文件不存在!!!"<<endl;return false;
}void Close()
{string file_name;UFD *pu=pufd->next;cout<<"請輸入要關閉的文件名:";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) //可寫的文件才有權把新寫入的數據也保存起來嘛{while(pu){if(temp->File_name==pu->File_name){pu->File_length=temp->Pointer;break;}pu=pu->next;}}delete temp;cout<<"文件"<<file_name<<"關閉成功!!!"<<endl;return ;}p=p->next;}cout<<"抱歉,要關閉的文件沒有被打開!!!"<<endl;
}bool Read_File() //因為讀寫都是通過修改運行文件目錄的Pointer去模擬的嘛
{string File_name; //你要讀文件的話,你這文件肯定得在運行/打開文件目錄里面,是吧unsigned int length;AFD *p=pafd->next;cout<<"請輸入要讀的文件名:";cin>>File_name;cout<<"請輸入要讀取的長度:"; //讀取的話,實際中文件的長度并不會改變cin>>length; //即讀取的長度并不能保存回去,為了方便(如果用戶是讀數據的話,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() //寫的話,自然是運行文件目錄
{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<<"請寫入指定長度的內容:<以回車作為結束符>"<<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<<"欲寫入的數據大小發生溢出,已超過文件的分配容量,寫入失敗!!!"<<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(); //該語句待定,這語句真的用的很妙,因為我并沒有馬上退出這次函數調用了}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]) //如果文件沒有數據的話,就用空格表示此文件沒有任何內容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<<"************************二級文件系統演示*************************"<<endl;cout<<"*\t\t命令 說明 *"<<endl; cout<<"*\t\tlogin 登錄系統 *"<<endl; cout<<"*\t\tcreate 創建文件 *"<<endl; cout<<"*\t\tdelete 刪除文件 *"<<endl; cout<<"*\t\topen 打開文件 *"<<endl; cout<<"*\t\tclose 關閉文件 *"<<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 退出系統 *"<<endl; cout<<"*****************************************************************"<<endl;
}void System_Init()
{
Start:Print_Help();Init_Disk();if(!Init_MFD()){int num;cout<<"主目錄還未創建,是否創建<y/n>!!!"<<endl;cin>>flag;cout<<"請輸入欲創建的用戶文件夾的個數(1-10):"<<endl;cin>>num;if(flag=='y'){while(num--){Create_MFD();if(!Max_User){ cout<<"本系統,最多支持10個用戶,創建多余用戶失敗,請刪除其他用戶,再做嘗試!!!"<<endl;return ;}}Save_MFD();cout<<"主目錄已經創建完成,用戶各自目錄已得到保存,是否繼續<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;
}
總結
以上是生活随笔為你收集整理的操作系统课程设计之二级文件系统演示的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。