版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
操作系統(tǒng)實驗報告操作系統(tǒng)實驗報告題目: 文件管理系統(tǒng)班級:目錄一、 實踐內容 31.1實驗內容 32.實驗原理 43、實驗要求 4二、 實驗的目的及意義 4三、 詳細設計 53.1功能設計 53.2結構設計 63.3核心算法 113.4數(shù)據(jù)結構 11四、調試分析 134.1運行環(huán)境 134.2調試分析 13五、缺點及改進 135.1實驗缺點 135.2實驗改進 13六、實驗總結 13七、參考文獻 14八、附錄 148.1個人心得 148.2源程序 15實踐內容1.1實驗內容通過一個簡單的二級文件系統(tǒng)設計,加深對文件系統(tǒng)的內部功能以及內部實現(xiàn)的理解。要求模擬采用二級目錄結構的磁盤文件系統(tǒng)的文件操作能實現(xiàn)以下幾條命令,用輸入命令來模擬用戶程序中調用的文件操作:Login用戶登錄用戶輸入用戶名和密碼,在passwd文件中查找是否有此用戶,核對密碼。正確則登陸成功,當前目錄設定到當前用戶文件夾下。format格式化初始化超級塊,初始化主目錄,初始化管理員admin目錄,初始化用戶目錄,初始化用戶passwd文件。create創(chuàng)建文本文件查找當前目錄下是否有同名文件,是則退出,否則讓用戶輸入文本文件內容,以‘###’結束。申請硬盤空間,申請失敗則結束。將文件內容寫入硬盤空間。修改當前目錄的結構,修改超級塊。cdir創(chuàng)建文件夾查找當前目錄下是否有同名文件,是則退出,否則,申請硬盤空間,申請失敗則結束。將文件夾內容寫入硬盤空間。修改當前目錄的結構,修改超級塊,寫入模擬硬盤。readedit讀取和追加文本文件Read查找當前目錄下是否該文件,沒有則退出,否則調用access()權限判斷,有權限則判斷是不是文件,不是則退出,是文件則讀取文件并顯示。Edit調用讀取文件模塊,讀取成功則用戶輸入追加的內容,如果追加的內容大于一個硬盤分配空間則申請分配空間,失敗則退出,申請成功則保存文件。access(文件名)權限判斷,先判斷當前目錄是否有該文件,在當前目錄的硬盤空間找到該文件,判斷當前登錄用戶是哪個組,判斷是否該用戶創(chuàng)建,判斷該文件的可見級別。如果是該用戶創(chuàng)建的則有讀寫權限如果當前用戶是管理員組的也具有讀寫權限如果該文件是用戶可查看文件則都具有權限。cd進入子目錄或上級目錄,查找當前目錄是否有該子目錄,沒有則退出,調用access()判斷當前用戶是否有權限,無則退出,有則讀取該子目錄的目錄,將當前目錄指向該目錄。attr(文件名)查看文件或者文件夾的屬性,先查找當前目錄下是否有該文件或目錄,有則判斷文件是否系統(tǒng)文件,是否文本文件,是否目錄,由誰創(chuàng)建,屬于什么組,占用的空間和目錄。將其全部顯示出來。Del刪除文件或目錄。查找當前目錄是否有該文件名,沒有則退出,有則調用access()判斷是否有權限,有則判斷是否為系統(tǒng)文件,是則無法刪除,不是則判斷是否是文件,是文件則直接刪除,不是則判斷是否文件夾,是文件夾則判斷該文件夾下是否有文件,有文件則無法刪除。提示用戶是否刪除,確認則刪除文件,修改當前文件夾目錄和硬盤空間結構,修改超級塊,寫入模擬硬盤。Dir列文件目錄(列出文件名、物理地址、保護碼和文件長度)2.實驗原理文件系統(tǒng)管理中用到的數(shù)據(jù)結構有:(1)首先應確定文件系統(tǒng)的數(shù)據(jù)結構:主目錄、子目錄及活動文件等。主目錄和子目錄都以文件的形式存放于磁盤,這樣便于查找和修改。(2)用戶創(chuàng)建的文件,可以編號存儲于磁盤上。如:file0,file1,file2…并以編號作為物理地址,在目錄中進行登記。3、實驗要求(1)設計一個10個用戶的文件系統(tǒng),每次用戶可保存10個文件,一次運行用戶可以打開5個文件。(2)程序采用二級文件目錄(即設置主目錄MFD)和用戶文件目錄(UFD)。另外,為打開文件設置了運行文件目錄(AFD)。(3)為了便于實現(xiàn),對文件的讀寫作了簡化,在執(zhí)行讀寫命令時,只需改讀寫指針,并不進行實際的讀寫操作。(4)文件保護簡單使用了三位保護碼:允許讀寫執(zhí)行、對應位為1,對應位為0,則表示不允許讀寫、執(zhí)行。實驗的目的及意義課程設計目的使學生熟悉文件管理系統(tǒng)的設計方法;加深對所學各種文件操作的了解及其操作方法的特點。通過模擬文件系統(tǒng)的實現(xiàn),深入理解操作系統(tǒng)中文件系統(tǒng)的理論知識,加深對教材中的重要算法的理解。同時通過編程實現(xiàn)這些算法,更好地掌握操作系統(tǒng)的原理及實現(xiàn)方法,提高綜合運用各專業(yè)課知識的能力。詳細設計3.1功能設計Help 顯示命令幫助dir 顯示當前目錄下的文件和文件夾logout 注銷exit 退出系統(tǒng)create[文件名] 創(chuàng)建文本文件cdir[目錄名] 創(chuàng)建文件夾read[文件名] 讀取一個文件最多可同時讀取五個close[文件名] 關閉一個文件edit[文件名] 編輯一個文件cd[目錄名] 進子目錄或者上級目錄attr[文件名] 顯示該文件的屬性del[文件名] 刪除文件rename[文件名] 重命名3.2結構設計1)總設計結構圖 2)目錄結構示意圖3)流程圖 編輯功能流程圖 創(chuàng)建文件流程圖刪除文件功能流程圖 3.3核心算法boolFormat(void); //格式化boolinstall(void); //裝載虛擬硬盤的數(shù)據(jù)voidlogin(void); /用戶登陸voidshowMenu(void);//顯示功能菜單boolonAction(void);//用戶選擇功能并執(zhí)行voidshowDir();//顯示當前文件夾里面文件的信息voidlogout();//注銷voidcreateFile(stringstr);//創(chuàng)建文件voidcreateDir(stringstr);//創(chuàng)建文件夾boolread(stringstr);//讀取文件voideditFile(stringstr);//編輯文件intvisit(stringstr);//打開一個文件夾voidattrib(stringstr);//顯示文件屬性voidDelete(stringstr);//刪除一個文件intrename(stringstr);//重命名一個文件3.4數(shù)據(jù)結構/*常變量*/constunsignedintBLOCK_SIZE=512; //塊長constunsignedintDATA_BLOCK_NUM=512; //數(shù)據(jù)塊數(shù)量constunsignedintDINODE_START=4*BLOCK_SIZE; //inode起始位置constunsignedintDINODE_SIZE=512; //inode大小constunsignedintDINODE_NUM=32; //inode數(shù)量constunsignedintDATASTART=(2+DINODE_NUM)*BLOCK_SIZE; //數(shù)據(jù)區(qū)的開始地址constunsignedintACCOUNT_NUM=10; //用戶數(shù)量/*inode結構體*/structinode{ unsignedshortdi_tag; /*inode標識*/ unsignedshortdi_number; /*關聯(lián)文件數(shù),當為0時表示刪除文件,如一個目錄至少包含兩個文件:"."和".."*/ unsignedshortdi_mode; /*存取模式:0為目錄,1為文件*/ unsignedshortdi_userID; /*當前inode所屬用戶0為根目錄ID,一次下去是管理員目錄、用戶目錄*/ unsignedshortdi_access; /*訪問權限0為不允許普通用戶訪問(公共目錄),1為允許普通用戶訪問*/ unsignedshortdi_size; /*文件大小,目錄沒有大小,值為0*/ unsignedshortdi_ctime;/*創(chuàng)建時間*/ unsignedshortdi_mtime;/*最后一次修改時間*/ unsignedshortdi_block[DATA_BLOCK_NUM];/*數(shù)據(jù)塊塊地址編號*/};/**超級塊***/structsuper_block{ unsignedshorts_inodes_count;/*文件系統(tǒng)中inode的總數(shù)*/ unsignedshorts_blocks_count;/*數(shù)據(jù)塊總數(shù)*/ unsignedshorts_r_blocks_count;/*保留塊總數(shù)*/ unsignedshorts_free_blocks_count;//空閑塊總數(shù) unsignedshorts_free_inodes_count;/*空閑的inode總數(shù)*/ unsignedshorts_log_block_size;/*block的大小*/};/**賬戶信息**/structuser{ unsignedshortuser_id; //用戶ID unsignedshortuser_access; //權限 stringusername; //用戶名 stringpassword; //密碼};/**文件/目錄結構**/structdirectory{ stringname; /*目錄名*/ unsignedshortd_ino; /*目錄號*/};四、調試分析4.1運行環(huán)境 編譯平臺:MicrosoftVisualStudio2010 運行平臺:win7/xp4.2調試分析五、缺點及改進5.1實驗缺點 由于對Linux的文件系統(tǒng)理解不夠深刻,導致程序在一些原理上的迷糊不清,而時間較短,因此采取了簡化或者放開的方法。在寫程序的開始,也沒有做詳細的規(guī)劃,而且是四個人分工協(xié)作,因此在程序的結構上有些混亂。在后期做了一些調整,但是整體還是有缺陷的。另外,程序只是很簡單的模擬了Linux的文件管理系統(tǒng),只有一些非常簡單的功能,而且功能考慮的也不盡全面、嚴謹,難免會出現(xiàn)一些Bug,另外,我們整體在寫的時候是用的C++的寫法,但是在編寫的時候,又混用了c的一些方法,所以,整個程序更加混亂,給閱讀理解帶來非常大的困難。5.2實驗改進 首先,我們先要把一些原理知識搞清楚,其次,做一個統(tǒng)一的項目規(guī)劃,做好一些定義的聲明,結構再清晰一些。更深層次的模擬Linux文件管理系統(tǒng),將一些函數(shù)的考慮更加嚴謹、全面,多次調試,減少一些bug。盡量用規(guī)范的C++語言才編寫,注清函數(shù)功能,便于相互分享調用閱讀。六、實驗總結 本實驗是模擬Linux文件管理系統(tǒng),而我們平時很少接觸到Linux系統(tǒng),只是在書上學了一些理論的皮毛,紙上得來總覺淺,因此在開始做的時候,感覺無從下手,只能去網上去查找一些相關知識,以及看老師給的例子,并且和其他組就行討論,這個時間花了一天半的時間,但是成果不是很好,很多地方都不明白。但是時間緊迫,我們就邊做邊理解、討論,這樣造成一個非常大的困難,不知道從哪里下手,只能模仿著做,加深理解。在兩天的倉促的時間里面,我們做出了一個簡單可行的模擬文件系統(tǒng),雖然問題不少,但是在時間的允許下,我們還是不錯的。 在編程中,我們遇到了很多以前沒有遇到的問題和知識,在通過相互討論,上網查詢等方法后,我們解決了大部分的問題,對C++語言的理解也加深了很多,對一個項目的需求也理解很多,一個合理的規(guī)劃會提高不少效率。七、參考文獻《C++程序設計》 清華大學出版社 譚浩強《算法與數(shù)據(jù)結構(第二版)》 高等教育出版社 張乃孝《操作系統(tǒng)教程(第四遍)》 高等教育出版社 孫鐘秀 8.2源程序#include<iostream>#include<string>#include<stdio.h>usingnamespacestd;/*常變量*/constunsignedintBLOCK_SIZE=512; //塊長constunsignedintDATA_BLOCK_NUM=512; //數(shù)據(jù)塊數(shù)量constunsignedintDINODE_START=4*BLOCK_SIZE; //inode起始位置constunsignedintDINODE_SIZE=512; //inode大小constunsignedintDINODE_NUM=512; //inode數(shù)量constunsignedintDATA_START=(2+DINODE_NUM)*BLOCK_SIZE; //數(shù)據(jù)區(qū)的開始地址constunsignedintACCOUNT_NUM=10; //用戶數(shù)量constunsignedintDIRECTORY_NUM=12; //每個目錄最多允許擁有的子目錄和文件constunsignedshortFILE_NAME_LENGTH=20; //最大文件名長度/**************************inode結構體**************************//*inode結構體*/structinode{ unsignedshortdi_tag; /*inode標識*/unsignedshortdi_number; /*關聯(lián)文件數(shù),當為0時表示刪除文件,如一個目錄至少包含兩個文件:"."和".."*/ unsignedshortdi_mode; /*存取模式:0為目錄,1為文件*/ unsignedshortdi_userID; /*當前inode所屬用戶0為根目錄ID,一次下去是管理員目錄、用戶目錄*/ unsignedshortdi_access; /*訪問權限0為不允許普通用戶訪問(公共目錄),1為允許普通用戶訪問*/ unsignedshortdi_size; /*文件大小,目錄沒有大小,值為0*/ unsignedshortdi_ctime;/*創(chuàng)建時間*/ unsignedshortdi_mtime;/*最后一次修改時間*/ unsignedshortdi_block;/*數(shù)據(jù)塊塊地址編號*/};/*———————————————————————— 超級塊結構————————————————————————*/structsuper_block{ unsignedshorts_inodes_count;/*文件系統(tǒng)中inode的總數(shù)*/ unsignedshorts_free_inodes_count;/*空閑的inode總數(shù)*/ unsignedshorts_blocks_count;/*塊總數(shù)*/ unsignedshorts_r_blocks_count;/*保留塊總數(shù)*/ unsignedshorts_free_blocks_count;//空閑塊總數(shù) unsignedshorts_log_block_size;/*block的大小*/// unsignedshorts_free_blocks_group[GROUPNUM];//新增一個數(shù)組來記錄每個數(shù)據(jù)塊組中的空閑數(shù)據(jù)塊計數(shù)// unsignedshorts_first_data_block;/*第一個數(shù)據(jù)block*/ // unsignedshorts_blocks_per_group;/*每blockgroup的block數(shù)量*/// unsignedshorts_inodes_per_group;/*每blockgroup的inode數(shù)量*/ };/*———————————————————————— 賬戶信息————————————————————————*/structuser{ unsignedshortuser_id; //用戶ID unsignedshortuser_access; //權限1為管理員0為平民 stringusername; //用戶名 stringpassword; //密碼};/*———————————————————————— 文件、目錄項結構————————————————————————*/structdirectory{ stringname; /*目錄、文件名*/ stringcontent;/*文件數(shù)據(jù),目錄則沒有數(shù)據(jù)*/ unsignedshortd_ino; /*目錄、文件號*/};/*變量*/unsignedshortdi_bitmap[DINODE_NUM]; //硬盤inode節(jié)點位圖1表示已使用0表示未使用unsignedshort bk_bitmap[DATA_BLOCK_NUM]; //數(shù)據(jù)塊block位圖structsuper_blocksuperBlock; //超級塊structuseraccount[ACCOUNT_NUM]; //共創(chuàng)建ACCOUNT_NUM個賬戶FILE*f_stream; //文件指針structinode*cur_inode; //inode當前目錄指針structinode*inode_temp; //inode臨時指針 constchardiskName[30]="ext2forlinux.disk"; //模擬硬盤的文件名structdirectorydir_buf[DIRECTORY_NUM]; //目錄數(shù)組,每個目錄最多允許有12個項(子目錄或者文件)stringcur_Path;//cmd的頭表示所在哪個文件夾//inti_lock=0;//inode位圖鎖可能會多線程//intb_lock=0;//block位圖鎖structuser*cur_user; //當前用戶structdirectorycur_dir[DIRECTORY_NUM];//當前目錄/**********************函數(shù)聲明********************/boolFormat(void); //此函數(shù)用于格式化boolinstall(void); //此函數(shù)用于裝載虛擬硬盤的數(shù)據(jù)intFindFile(stringfilename);//次函數(shù)用于查找當前文件夾是否有該文件 boolaccess(structinode*pinode);//權限判斷intmain(){ voidlogin(void); //此函數(shù)用于用戶登陸 voidshowMenu(void);//此函數(shù)用于顯示功能菜單 boolonAction(void);//此函數(shù)用于用戶選擇功能并執(zhí)行 charformat_bool; /**************初始化************/ cout<<"系統(tǒng)已啟動,是否初始化所有數(shù)據(jù)?\tY/N"<<endl; while(true){ cin>>format_bool; if(format_bool=='y'||format_bool=='Y'){ if(!Format())return0; break; } elseif(format_bool=='n'||format_bool=='N'){ cout<<"不初始化不能開始!"<<endl; continue; } else{ cout<<"請輸入Y或者N"<<endl; continue; } } cout<<"初始化成功!"<<endl; /********轉載虛擬硬盤數(shù)據(jù)***********/ if(!install()){ cout<<"加載失敗,無效的硬盤格式"<<endl; //main(); return0; } elsecout<<"加載disk成功!"<<endl; cur_Path=cur_dir[1].name+"\\root"; /*******登陸**********/ login(); /**顯示菜單**/ showMenu(); /**顯示當前路徑**/ cout<<cur_Path; while(onAction()); return0;}/*此函數(shù)用于格式化*/boolFormat(){ //創(chuàng)建文件 f_stream=fopen(diskName,"wb+"); if(f_stream==NULL){ cout<<"創(chuàng)建文件失敗"<<endl; returnfalse; } //初始化超級塊 superBlock.s_inodes_count=DINODE_NUM;/*文件系統(tǒng)中inode的總數(shù)*/ superBlock.s_free_inodes_count=DATA_BLOCK_NUM-2-ACCOUNT_NUM;/*空閑的inode總數(shù)初始化時,主目錄和賬戶信息各占一塊,10個用戶10塊*/ superBlock.s_blocks_count=DATA_BLOCK_NUM;/*塊總數(shù)*/ superBlock.s_free_blocks_count=DATA_BLOCK_NUM-2-ACCOUNT_NUM;//空閑塊總數(shù)主目錄/10個用戶/賬戶信息共占用12個 superBlock.s_log_block_size=BLOCK_SIZE;/*block的大小*/ //超級塊放第1個物理塊,第0個為引導 fseek(f_stream,BLOCK_SIZE,SEEK_SET); fwrite(&superBlock,BLOCK_SIZE,1,f_stream);// fprintf(f_stream,"thisissuperblock");//測試 //初始化dinode位圖block位圖 for(inti=0;i<DATA_BLOCK_NUM;i++){ if(i<2+ACCOUNT_NUM)bk_bitmap[i]=1; elsebk_bitmap[i]=0; } //初始化block位圖 for(inti=0;i<DINODE_NUM;i++){ if(i<2+ACCOUNT_NUM)di_bitmap[i]=1; elsedi_bitmap[i]=0; } //位示圖存放與第2.3塊 fseek(f_stream,BLOCK_SIZE*2,SEEK_SET); fwrite(&di_bitmap,BLOCK_SIZE,1,f_stream);// fprintf(f_stream,"thisissuperblock");//測試 fseek(f_stream,BLOCK_SIZE*3,SEEK_SET); fwrite(&bk_bitmap,BLOCK_SIZE,1,f_stream);// fprintf(f_stream,"thisissuperblock");//測試 //初始化inode表 structinode*node_temp; node_temp=newinode; if(!node_temp) { printf("node_temp內存分配失敗!"); returnfalse; } //主目錄的inode node_temp->di_tag=0;//i節(jié)點標志 node_temp->di_number=2+ACCOUNT_NUM;//關聯(lián)12個文件夾 node_temp->di_mode=0;//0為目錄 node_temp->di_userID=0;//用戶id第一個用戶 node_temp->di_access=0;//0為公共可以訪問 node_temp->di_size=0;//目錄無size node_temp->di_ctime=0;/*創(chuàng)建時間*/ node_temp->di_mtime=0;/*修改時間*/ node_temp->di_block=0; fseek(f_stream,DINODE_START,SEEK_SET); fwrite(node_temp,sizeof(structinode),1,f_stream); //賬戶信息的inode node_temp->di_tag=1; node_temp->di_number=0;//無文件關聯(lián),此項等于0表明是賬戶信息,可用作區(qū)別于文件、目錄的標識 node_temp->di_mode=0;//0為目錄 node_temp->di_userID=0;//用戶id第一個用戶 node_temp->di_access=0;//0為公共可以訪問 node_temp->di_size=0;//無size node_temp->di_ctime=0;/*創(chuàng)建時間*/ node_temp->di_mtime=0;/*修改時間*/ node_temp->di_block=1; /**賬戶信息存在數(shù)據(jù)塊的第1塊**/ fseek(f_stream,DINODE_START+BLOCK_SIZE,SEEK_SET); fwrite(node_temp,sizeof(structinode),1,f_stream); //管理員和9個普通用戶的inode for(inti=1;i<=ACCOUNT_NUM;i++){ node_temp->di_tag=i+1;//inode標志 node_temp->di_number=2;//關聯(lián)2個文件夾 node_temp->di_access=1;//1為用戶私有 node_temp->di_mode=0;//0為目錄 node_temp->di_userID=i;//用戶id第一個用戶 node_temp->di_size=0;//目錄無size node_temp->di_ctime=0;/*創(chuàng)建時間*/ node_temp->di_mtime=0;/*修改時間*/ node_temp->di_block=i+1;//所占物理塊號.從管理員到user9占用的位置為2~11. fseek(f_stream,DINODE_START+BLOCK_SIZE*(i+1),SEEK_SET); fwrite(node_temp,sizeof(structinode),1,f_stream); } /*******初始化主目錄**********/ dir_buf[0].name="."; dir_buf[0].d_ino=0; dir_buf[1].name=".."; dir_buf[1].d_ino=0; dir_buf[2].name="admin"; dir_buf[2].d_ino=2;//管理員的inode號為2 //user1~user9的目錄項 for(inti=0;i<ACCOUNT_NUM-1;i++){ dir_buf[i+3].name="user"+i; dir_buf[i+3].d_ino=i+3; } fseek(f_stream,DATA_START,SEEK_SET); fwrite(dir_buf,BLOCK_SIZE,1,f_stream); /**初始化賬戶信息**/ structuseraccount_temp[ACCOUNT_NUM]; //管理員賬戶 account_temp[0].username="admin"; account_temp[0].password="admin"; account_temp[0].user_access=1;//1為管理員 account_temp[0].user_id=2;//管理員目錄的塊號 //user1~user9 for(inti=1;i<ACCOUNT_NUM;i++){ account_temp[i].username="user"+i; account_temp[i].password="user"+i; account_temp[i].user_access=0; account_temp[i].user_id=i+2;//user[i]的物理塊號 } fseek(f_stream,DATA_START+BLOCK_SIZE,SEEK_SET); fwrite(account_temp,BLOCK_SIZE,1,f_stream); /**初始化admin目錄以及user1~user9**/ //清空dir_buf for(inti=0;i<DIRECTORY_NUM;i++){ dir_buf[i].d_ino=0; dir_buf[i].name="\0"; } for(inti=0;i<ACCOUNT_NUM;i++){ dir_buf[0].d_ino=2; dir_buf[0].name="."; dir_buf[1].d_ino=0; dir_buf[1].name=".."; fseek(f_stream,DATA_START+BLOCK_SIZE*(i+2),SEEK_SET);//管理員在第二塊物理空間 } returntrue;}/*此函數(shù)用于裝載虛擬硬盤的數(shù)據(jù)*/boolinstall(void){ /**函數(shù)聲明**/ inode*getInode(unsignedint);//獲取指定inode號的inode單元 boolgetDataBlock(unsignedint);//獲取指定數(shù)據(jù)塊號下的目錄或文件 inti; cout<<"installing..."<<endl; f_stream=fopen(diskName,"rb+");//只讀方式打開硬盤模擬文件 if(f_stream==NULL) { cout<<"文件打開失敗"<<endl; return0; } //讀超級塊 fseek(f_stream,BLOCK_SIZE,SEEK_SET); fread(&superBlock,sizeof(structsuper_block),1,f_stream); ////// cout<<"加載超級塊:"<<superBlock.s_blocks_count<<endl; inode_temp=newinode; if(!inode_temp) { cout<<"cur_inode內存分配失敗!"<<endl; return0; } cur_inode=newinode; if(!cur_inode) { cout<<"cur_inode內存分配失敗!"<<endl; return0; } //讀取inode位示圖 fseek(f_stream,BLOCK_SIZE*2,SEEK_SET); fread(di_bitmap,BLOCK_SIZE,1,f_stream); cout<<"加載inode位示圖:"<<di_bitmap[0]<<endl; //讀取block位示圖 fseek(f_stream,BLOCK_SIZE*3,SEEK_SET); fread(bk_bitmap,BLOCK_SIZE,1,f_stream); cout<<"加載block位示圖:"<<bk_bitmap[0]<<endl; //讀取賬戶信息的inode inode_temp=getInode(1); if(inode_temp==NULL) { cout<<"加載賬戶信息失敗!"<<endl; returnfalse; } //changeinode();//交換指針后cur_inode指向當前目錄的inode //讀取賬戶信息 cout<<"賬戶信息塊號:"<<inode_temp->di_block<<endl; fseek(f_stream,DATA_START+BLOCK_SIZE*inode_temp->di_block,SEEK_SET); fread(account,BLOCK_SIZE,1,f_stream); cout<<"加載賬戶信息:"<<account[0].username<<'\t'<<account[0].password<<endl; for(i=0;i<ACCOUNT_NUM;i++) { if(account[i].user_id!=0) { cout<<account[i].username<<account[i].password; } } cur_inode=getInode(0);//讀取主目錄的inode當前inode指向主目錄的inode if(cur_inode->di_mode!=0) { cout<<"讀取主目錄失敗,請重新格式化!"<<endl; } else { //將主目錄讀入cur_dir數(shù)組 getDataBlock(cur_inode->di_block); } returntrue;}/*此函數(shù)用于用戶登陸*/voidlogin(){ }/*此函數(shù)用于顯示功能菜單*/voidshowMenu(void){ cout<<"help\t\t顯示命令幫助\n"; cout<<"create[文件名]\t創(chuàng)建文本文件\n"; cout<<"cdir[目錄名]\t創(chuàng)建文件夾\n"; cout<<"read[文件名]\t讀取一個文件\n"; cout<<"edit[文件名]\t編輯一個文件\n"; cout<<"cd[目錄名]\t進入子目錄或者上級目錄\n"; cout<<"attr[文件名]\t顯示該文件的屬性\n"; cout<<"del[文件名]\t刪除文件\n"; cout<<"dir\t\t顯示當前目錄下的文件和文件夾\n"; cout<<"rename[文件名]\t重命名\n"; cout<<"logout\t\t注銷\n"; cout<<"exit\t\t退出系統(tǒng)\n";}/**此函數(shù)用于用戶選擇功能并執(zhí)行**/boolonAction(){ voidshowMenu(); voidshowDir(); voidlogout(); voidcreateFile(stringstr);//創(chuàng)建一個文件 voidcreateDir(stringstr); voideditFile(stringstr); voidvisit(stringstr); voidattrib(stringstr); voidDelete(stringstr);//刪除一個文件 voidrename(stringstr); boolread(stringfilename);//此函數(shù)用于讀取一個文件 inode*getInode(unsignedint); fflush(stdin); while(true){ fflush(stdin); charstr[20];//用戶輸入的命令 charname[20];//文件或者目錄名 stringnamestr; cin>>str; // cout<<"str="<<str<<endl; // cout<<"測試:"<<str.find_first_of("create",0)<<'\t'<<str.find_first_of("",0)<<'\t'<<endl; if(strcmp(str,"exit")==0){ fclose(f_stream); returnfalse; } elseif(strcmp(str,"dir")==0){ showDir();//顯示當前文件夾下的所有文件和文件夾 } elseif(strcmp(str,"help")==0){ showMenu(); //顯示功能菜單 } elseif(strcmp(str,"logout")==0){ logout();//注銷 } elseif(strcmp(str,"create")==0){ cin>>namestr; createFile(namestr); } elseif(strcmp(str,"cdir")==0){ cin>>namestr; createDir(namestr);//創(chuàng)建文件夾 } elseif(strcmp(str,"read")==0){ cin>>name; read(name);//讀文件 } elseif(strcmp(str,"edit")==0){ cin>>name; editFile(name);//編輯文件 } elseif(strcmp(str,"cd")==0){ cin>>name; visit(name);//目錄訪問 } elseif(strcmp(str,"attr")==0){ cin>>name; attrib(name);//顯示該文件的屬性 } elseif(strcmp(str,"del")==0){ cin>>name; Delete(name);//刪除文件 } elseif(strcmp(str,"rename")==0){ cin>>name; rename(name);//重命名 } /**測試**/ elseif(strcmp(str,"getInode")==0){ inti; cin>>i; getInode(i);//查看inode } /*****/ elsecout<<str<<"不是內部命令!"<<endl; }}/**此函數(shù)用于顯示當前目錄下所有文件和文件夾信息**/voidshowDir(void){ cout<<"thisisshowDir"<<endl;}/**此函數(shù)用于注銷用戶**/voidlogout(void){ cout<<"thisislogout"<<endl;}/**此函數(shù)用于創(chuàng)建文件夾**/voidcloseFile(stringstr){ cout<<"thisiscloseFile"<<endl;}/**此函數(shù)用于編輯文件**/voideditFile(stringstr){ cout<<"thisiseditFile"<<endl;}/**訪問目錄**/voidvisit(stringstr){ cout<<"thisisvisit"<<endl;}/**顯示文件屬性**/voidattrib(stringstr){ cout<<"thisisattrib"<<endl;}/**文件或者目錄重命名**/voidrename(stringstr){ cout<<"thisisrename"<<endl;}/**此函數(shù)判斷對要訪問的文件夾是否有訪問權限**/boolaccess(structinode*pinode)//調用的時候要把當前文件的inode指針傳送過來這里0表示普通用戶1表示管理員{ if(pinode->di_userID==cur_user->user_id)returntrue;//該文件是當前用戶擁有 if(cur_user->user_access==1)returntrue;//該用戶為管理員 returnfalse;}/**此函數(shù)用于讀取相應inode號下面的inode塊**/structinode*getInode(unsignedintn){ inode*temp; temp=newinode; fseek(f_stream,DINODE_START+BLOCK_SIZE*n,SEEK_SET); fread(temp,sizeof(structinode),1,f_stream);// cout<<"inode:\n"<<"di_tag:"<<temp->di_tag<<"\tdi_number:"<<temp->di_number<<"\tdi_mode:"<<temp->di_mode<<"\tdi_userID:"<<temp->di_userID<<"\ndi_block:"<<temp->di_block<<endl; returntemp; }/**此函數(shù)將指定編號下的數(shù)據(jù)塊的目錄或者文件讀入cur_dir**/boolgetDataBlock(unsignedintn){ //directory*temp; //temp=newdirectory; fseek(f_stream,DATA_START+BLOCK_SIZE*n,SEEK_SET); fread(cur_dir,sizeof(structdirectory)*cur_inode->di_number,1,f_stream);// cout<<"getDataBlock函數(shù):"<<cur_dir[0].name<<'\t'<<cur_dir[0].d_ino<<endl; returntrue;}/**此函數(shù)用于判斷當前文件夾有沒有查找的文件沒有返回-1有返回該文件的inod號**/intFindFile(stringfilename){ inti; if(filename.length()>FILE_NAME_LENGTH){ cout<<"您輸入的文件名長度大于14,文件查找失??!"<<endl;return-1;}if(filename==".") { cout<<"自身文件夾不允許操作!"<<endl; return-1;} if(".."==filename) { cout<<"父目錄不允許操作!"<<endl; return-1;}for(i=0;i<cur_inode->di_number;i++){ if(dir_buf[i].name==filename) { cout<<"當前文件存在!"<<endl; returndir_buf[i].d_ino; }} cout<<"未找到此文件"<<endl; return-1;}/**此函數(shù)由于讀取一個文件,將文件內容輸出**/boolread(stringfilename){ structinode*temp; if(FindFile(filename)==-1) { returnfalse; } temp=getInode(FindFile(filename)); if(!access(temp)) { cout<<"您沒有此文件的訪問權限"<<endl; returnfalse; } if(temp->di_mode!=1) { cout<<filename<<"不是一個文件"<<endl; returnfalse; } char*buf; buf=(char*)malloc(BLOCK_SIZE*(temp->di_size/BLOCK_SIZE+1)); fseek(f_stream,DATA_START+BLOCK_SIZE*temp->di_block,SEEK_SET); fread(buf,BLOCK_SIZE*(temp->di_size/BLOCK_SIZE+1),1,f_stream); returntrue;}voidcreateFile(stringstr){ inti,j,m,file_access;if(str.length()>FILE_NAME_LENGTH){ cout<<"您輸入的文件名長度大于20,文件創(chuàng)建失??!";return;}if(FindFile(str)!=-1){ cout<<"您輸入的文件名已存在,文件名不能重復,創(chuàng)建失??!"<<endl; return;}if(superBlock.s_free_inodes_count==0||superBlock.s_free_blocks_count==0){ cout<<"當前存儲空間已滿!請刪除一些文件后再存儲。"<<endl; return;}cout<<"請輸入文件的訪問權限。1表示共享文件,0表示私有文件:"<<endl;cin>>file_access;fflush(stdin);for(j=0;j<DINODE_NUM;j++){ if(di_bitmap[j]==0) { di_bitmap[j]=1; break; }}for(m=0;m<DATA_BLOCK_NUM;m++){ if(bk_bitmap[m]==0) { bk_bitmap[m]=1; break; } }char*buf;intk=0,tag=0;buf=(char*)malloc(BLOCK_SIZE*sizeof(char));cout<<"請輸入文件的內容,以“###”結束!"<<endl;for(i=0;i<BLOCK_SIZE;i++){ buf[i]=getchar();if(tag==0)k=0;if(buf[i]=='#') { tag=1; k++; if(k==3) break; } else { k=0; tag=0;}}buf[i-2]='\0';cout<<"文件長度為:"<<strlen(buf);structinode*node_temp; node_temp=newinode; if(!node_temp) { cout<<"node_temp內存分配失敗!文件創(chuàng)建不成功!"<<endl; return; }node_temp->di_tag=j;node_temp->di_number=1; /*關聯(lián)文件數(shù),當為0時表示刪除文件,如一個目錄至少包含兩個文件:"."和".."*/node_temp->di_mode=1; /*存取模式:0為目錄,1為文件*/node_temp->di_userID=cur_user->user_id; /*當前inode所屬用戶0為根目錄ID,一次下去是管理員目錄、用戶目錄*/node_temp->di_access=file_access; /*訪問權限0為不允許普通用戶訪問(公共目錄),1為允許普通用戶訪問*/node_temp->di_size=strlen(buf); /*文件大小,目錄沒有大小,值為0*/node_temp->di_ctime;/*創(chuàng)建時間*/node_temp->di_mtime;/*最后一次修改時間*/node_temp->di_block=m;/*數(shù)據(jù)塊塊地址編號*/ fseek(f_stream,DINODE_START+j*BLOCK_SIZE,SEEK_SET);fwrite(node_temp,BLOCK_SIZE,1,f_stream);//將新建文件inode寫入磁盤fseek(f_stream,DATA_START+m*BLOCK_SIZE,SEEK_SET);fwrite(buf,BLOCK_SIZE,1,f_stream);//將新建文件的內容寫入磁盤dir_buf[cur_inode->di_number].d_ino=j;//修改當前目錄的結構dir_buf[cur_inode->di_number].name=str; fseek(f_stream,DATA_START+BLOCK_SIZE*cur_inode->di_block,SEEK_SET);//將當前目錄信息寫入文件的block區(qū)fwrite(dir_buf,BLOCK_SIZE,1,f_stream);cur_inode->di_number++;//當前目錄關聯(lián)文件數(shù)++superBlock.s_free_inodes_count--;//超級塊中空閑的inode數(shù)目減一superBlock.s_free_blocks_count--;//超級塊中空閑的block數(shù)目減一fseek(f_stream,BLOCK_SIZE,SEEK_SET);//修改超級塊fwrite(&superBlock,BLOCK_SIZE,1,f_stream);fseek(f_stream,2*BLOCK_SIZE,SEEK_SET);//fwrite(di_bitmap,BLOCK_SIZE,1,f_stream);fwrite(bk_bitmap,BLOCK_SIZE,1,f_stream);cout<<"文件已成功添加"<<endl;free(buf);return;}voidDelete(stringstr){ inti,j,m; intnumb;//numb用來存儲需要刪除的文件inode號charC;if(str.length()>FILE_NAME_LENGTH)//判斷輸入的文件名是否超過長度{ cout<<"您輸入的文件名長度大于20,操作失??!";return;}numb=FindFile(str);//判斷是否存在該文件或文件夾if(numb==-1){ cout<<"該文件或文件夾不存在!"<<endl; return;}if(!access(getInode(numb)))//判斷是否有權限刪除文件 { cout<<"您沒有權限刪除該文件或文件夾!"<<endl; return; }structinode*node_temp;//node_temp指向需要刪除文件inode結構體node_temp=getInode(numb);if(node_temp->di_mode==1)//如果是文件的話就直接刪除{ di_bitmap[numb]=0;//將文件inode釋放,即將相應位示圖位置置為0bk_bitmap[node_temp->di_block]=0;//將文件block釋放,即將相應位示圖位置置為0cur_inode->di_number--;//當前文件夾關聯(lián)文件減一for(i=0;i<node_temp->di_number;i++)//改變當前文件夾的關聯(lián)文件 { if(dir_buf[i].name==str) break; } for(j=i;j<node_temp->di_number-1;j++){ dir_buf[j]=dir_buf[j+1];}fseek(f_stream,DATA_START+BLOCK_SIZE*cur_inode->di_block,SEEK_SET);//將當前目錄信息寫入文件的block區(qū)fwrite(dir_buf,BLOCK_SIZE,1,f_stream);fseek(f_stream,2*BLOCK_SIZE,SEEK_SET);//修改位示圖fwrite(di_bitmap,BLOCK_SIZE,1,f_stream);fseek(f_stream,3*BLOCK_SIZE,SEEK_SET);fwrite(bk_bitmap,BLOCK_SIZE,1,f_stream);superBlock.s_free_inodes_count--;//超級塊中空閑的inode數(shù)目加一superBlock.s_free_blocks_count--;//超級塊中空閑的block數(shù)目加一fseek(f_stream,BLOCK_SIZE,SEEK_SET);//修改超級塊fwrite(&superBlock,BLOCK_SIZE,1,f_stream); }elseif(node_temp->di_mode==0)//是文件夾的話則判斷該文件夾中是否有文件{ if(node_temp->di_number>2)//如果有文件則不能刪除 { cout<<"當前文件夾內包含文件,不允許被刪除!"<<endl; return; }cout<<"是否真的要刪除該文件夾?(Y/N)";//若沒有文件則判斷是否要刪除該文件夾cin>>C;if(C=='N'||C=='n')return;elseif(C=='Y'||C=='y'){ di_bitmap[numb]=0;bk_bitmap[node_temp->di_block]=0;cur_inode->di_number--; for(i=0;i<node_temp->di_number;i++) { if(dir_buf[i].name==str) break; } for(j=i;j<node_temp->di_number-1;j++){ dir_buf[j]=dir_buf[j+1];}fseek(f_stream,DATA_START+BLOCK_SIZE*cur_inode->di_block,SEEK_SET);//將當前目錄信息寫入文件的block區(qū)fwrite(dir_buf,BLOCK_SIZE,1,f_stream);fseek(f_stream,2*BLOCK_SIZE,SEEK_SET);//修改位示圖fw
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 生物標志物在藥物臨床試驗中的轉化前沿進展
- 生物打印個性化皮膚模型在燒傷修復教學中的應用
- 深度解析(2026)《GBT 20674.1-2020塑料管材和管件 聚乙烯系統(tǒng)熔接設備 第1部分:熱熔對接》(2026年)深度解析
- 考試題解析質量管理體系考試難點解析
- 公關策劃師面試題目與解析
- 深度解析(2026)《GBT 19495.2-2004轉基因產品檢測 實驗室技術要求》
- 深度解析(2026)《GBT 19445-2004貴金屬及其合金產品的包裝、標志、運輸、貯存》
- 泰康保險品牌總監(jiān)面試題集
- 數(shù)據(jù)運營面試題集含答案
- 玫瑰痤瘡患者的心理支持方案
- 2025年植物標本采集合同協(xié)議
- 2025天津市第二批次工會社會工作者招聘41人考試筆試參考題庫及答案解析
- 校園反恐防暴2025年培訓課件
- 江西省人民防空工程標識標牌設置及制作規(guī)范圖冊(2021版)
- NB-T+10588-2021風力發(fā)電場集控中心運行管理規(guī)程
- 整理收納師課件
- 護工的溝通技巧
- 浮選藥劑及其作用原理資料課件
- 國開電大軟件工程形考作業(yè)3參考答案
- 皮部經筋推拿技術操作方法及常見疾病的皮部經筋推拿技術
- 冠脈痙攣診療進展
評論
0/150
提交評論