版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
文件系統(tǒng)實驗實驗目的和要求實驗目的通常把文件與管理信息資源的管理程序的集合稱為文件系統(tǒng),它是操作系統(tǒng)中負責存取和管理信息資源的模塊,采用統(tǒng)一的方法管理用戶信息和系統(tǒng)信息的存儲、檢索、更新、共享和保護,并為用戶提供一套行之有效的文件使用及操作方法。本實驗利用高級語言編寫程序模擬文件系統(tǒng),了解文件系統(tǒng)的基本結構和文件的各種操作方法,加深理解文件系統(tǒng)的內部功能及內部實現(xiàn),從而幫助學生對各種文件操作命令的實質內容和執(zhí)行過程有比較深入的了解。實驗要求1.采用高級語言編寫程序模擬文件系統(tǒng),文件系統(tǒng)采用多級目錄結構,實現(xiàn)對文件和目錄的創(chuàng)建、刪除、重命名、變更權限、顯示文件內容、修改文件內容等操作。2.撰寫實驗報告,報告應包含以下內容:(1)實驗目的;(2)實驗內容;(3)設計思路;(4)程序流程圖;(5)程序中主要數(shù)據(jù)結構和函數(shù)說明;(6)帶注釋的源程序代碼;(7)程序運行結果及分析(8)實驗收獲與體會預備知識文件和文件系統(tǒng)1.文件概念現(xiàn)代計算機系統(tǒng)中都配置了外存,大量的程序和數(shù)據(jù)以文件的形式存放在外存。如果由用戶直接管理文件,不僅要求用戶熟悉外存特性,了解各種文件的屬性,以及它們在外存上的位置,而且多用戶環(huán)境下還必須能保持數(shù)據(jù)的安全性和一致性,這是用戶不能勝任的。因而,現(xiàn)代操作系統(tǒng)中都配備文件系統(tǒng),以適應系統(tǒng)資源管理和用戶使用信息的需要。文件是指由創(chuàng)建者所定義的、具有文件名的一組相關元素的集合。用戶通過文件名就可對文件進行訪問,文件名是由字母或數(shù)字組成的字母或數(shù)字串,其格式和長度都因系統(tǒng)而異。操作系統(tǒng)提供文件系統(tǒng)的優(yōu)點有:(1)便于用戶使用。(2)文件安全可靠。(3)系統(tǒng)能有效利用存儲空間,優(yōu)化安排不同屬主文件的位置。(4)文件系統(tǒng)還能提供文件共享功能。2.文件命名在不同的操作系統(tǒng)中對文件名的規(guī)定有所不同,文件名的格式和長度因系統(tǒng)而異。一般來說,文件名由文件名和擴展名兩部分組成,前者用于標識文件,后者用于區(qū)分文件類型,中間用“.”分割開來,它們都是字母或數(shù)字所組成的字母數(shù)字串。早期文件名的長度僅限1~8個字符,現(xiàn)在文件名最長可達255個字符。擴展名是添加在文件名后面的若干個附加字符,又稱為后綴名,用于只是文件類型。例如,.txt指明純文本文件,.exe表示可執(zhí)行二進制代碼文件,.obj表示編譯或匯編生成的目標文件。3.文件類型 為便于管理和控制文件,將文件分為多種類型,下面是幾種常用的文件分類方法。 (1)按用途分類:系統(tǒng)文件,庫文件,用戶文件。 (2)按存取控制屬性分類:只讀文件,讀寫文件,不保護文件。 (3)按信息流向:輸入文件,輸出文件,輸入輸出文件。 (4)按文件中數(shù)據(jù)的形式分類:源文件,目標文件,可執(zhí)行文件。4.文件屬性文件屬性是指操作系統(tǒng)為文件配置的控制和管理信息,其目的是為方便系統(tǒng)和用戶對文件的管理和使用,這組屬性包括以下內容。(1)文件基本屬性:文件名和擴展名、文件屬性ID,文件所屬組ID等。(2)文件類型屬性:如普通文件、目錄文件、系統(tǒng)文件、隱藏文件、設備文件等。也可按文件信息分為ASCII碼文件、二進制碼文件等。(3)文件保護屬性:規(guī)定誰能夠訪問文件,以何種方式訪問。常用的文件訪問方式有可讀、可寫、可執(zhí)行、可更新、可刪除等;有的系統(tǒng)還為文件設置口令用作保護。(4)文件管理屬性:如文件創(chuàng)建時間、最后訪問時間、最后修改時間等。(5)文件控制屬性:文件邏輯結構信息,如:記錄鍵、記錄類型、記錄個數(shù)、記錄長度、成組因子數(shù)等;文件物理結構信息,如:文件所在設備名、物理設備類型、記錄存放的盤塊號或文件信息首選盤塊號,也可指出文件索引的位置等。 5.文件存取方法存取方法是指讀寫文件存儲器上的物理記錄的方法,由于文件類型不同,用戶使用的要求也不同,因而需要操作系統(tǒng)提供多種存取方法來滿足用戶要求。常用的存取方法如下:(1)順序存取。無論是無結構字節(jié)流文件還是有結構記錄式文件,存取操作都在上次操作的基礎上進行。順序存取主要用于磁帶文件,但也適用于磁盤上的順序文件。(2)直接存取。又稱隨機存取,可以非順序的從文件中的任何位置存取文件內容。它通常用于磁盤文件。(3)索引存取。這是基于索引文件的存取方法,由于文件中的記錄不按位置而是按其記錄名或記錄鍵來編址,所以用戶提供記錄名或記錄鍵之后,先按名搜索,再查找所需要的記錄。在實際系統(tǒng)中,大都采用多級索引以加速記錄的查找過程。6.文件系統(tǒng)文件系統(tǒng)是操作系統(tǒng)中負責管理和存取文件的程序模塊。它是由管理文件所需的數(shù)據(jù)結構和相應的管理軟件以及訪問文件的一組操作所組成。文件目錄為了對文件實施有效的管理,必須對它們加以妥善組織,這主要是通過文件目錄實現(xiàn)的。對目錄管理的要求如下:實現(xiàn)“按名存取”提高對目錄的檢索速度。實現(xiàn)文件共享允許文件重名1.文件控制塊文件控制塊(FileControlBlock,F(xiàn)CB)是操作系統(tǒng)為每個文件建立的唯一數(shù)據(jù)結構,其中包括了全部文件屬性,其目的是為了方便操作系統(tǒng)對文件的管理、控制和存取。于是一個文件有兩部分組成:FCB和文件體(文件信息)。有了FCB就可以方便的實現(xiàn)文件的按名存取。每當創(chuàng)建一個文件時,系統(tǒng)就要為其建立一個FCB,用來記錄文件的屬性信息;每當存取文件時,先找到其FCB,再找到文件信息盤塊號、首塊物理位置或索引表就能存取文件信息。2.一級目錄結構目錄結構的組織關系到文件系統(tǒng)的存取速度,也關系到文件的共享性和安全性。因此組織好文件的目錄,是設計好文件系統(tǒng)的重要環(huán)節(jié)。最簡單的文件目錄是一級目錄結構,所有FCB排列在一張線性表中。一級目錄的優(yōu)點是簡單,但它只能實現(xiàn)目錄管理中最基本的按名存取功能,文件重名和文件共享問題難以解決。3.兩級目錄結構兩級目錄結構將文件目錄分成主文件目錄和用戶文件目錄兩級。系統(tǒng)為每個用戶建立一個用戶文件目錄(UFD),每個用戶的文件目錄登記了該用戶建立的所有文件名及其屬性信息。主目錄(MFD)則登記了進入系統(tǒng)的各個用戶文件目錄的情況,每個用戶占一個表目,說明該用戶目錄的屬性,包括用戶名、目錄大小、組織形式及其所在的位置等。兩級目錄結構提高了目錄檢索的速度;允許不同的用戶目錄中使用相同的文件名;不同用戶也可以使用不同的文件名或相同的文件名來訪問系統(tǒng)中的同一個共享文件。兩級目錄結構雖然比較簡單實用,但缺乏靈活性,特別是難以反映現(xiàn)實世界的多層次關系。4.多級樹形目錄結構在現(xiàn)代操作系統(tǒng)中,所有文件系統(tǒng)都支持多級目錄結構,根目錄是唯一的,每一級目錄可以是下一級目錄的說明,也可以是文件的說明,從而形成樹狀目錄結構。如圖8.1是Linux目錄層次結構,它是一棵倒置的有根樹,樹根是根目錄,從根向下,每個樹枝是子目錄,而樹葉是文件。樹狀多級目錄結構有許多優(yōu)點,可以較好地反映現(xiàn)實世界中具有層次關系的數(shù)據(jù)結合,確切地反映系統(tǒng)內部文件的分支結構;不同文件可以重名,只要它們不位于同一末端子目錄中即可;易于規(guī)定不同層次或子目錄中文件的不同存取權限,便于文件的保護、保密和共享等,有利于系統(tǒng)的維護和查找。圖8.1Linux目錄層次結構文件結構在系統(tǒng)中的所有文件都存在著以下兩種形式的文件結構:文件的邏輯結構。這是從用戶觀點出發(fā)所觀察到的文件組織形式,即文件是由一系列的邏輯記錄組成的,是用戶可以直接處理的數(shù)據(jù)及其結構,它獨立于文件的物理特性。文件的物理結構。這是指系統(tǒng)將文件存儲在外存上所形成的一種存儲組織形式,是用戶不能看見的。文件的物理結構不僅與存儲介質的存儲性能有關,而且與所采用的外存分配方式有關。文件邏輯結構文件的邏輯結構分為兩種形式:流式文件和記錄式文件。(1)流式文件這是一種無結構的文件,文件內的數(shù)據(jù)不再組成紀錄,只是一串順序的信息集合,稱為字節(jié)流文件。流式文件中的每個字節(jié)都有一個索引,第一個字節(jié)的索引為0,第二個字節(jié)的索引為1……打開文件的進程使用文件讀寫指針來訪問文件中的特定字節(jié)。當文件打開時,文件讀寫指針指向首字節(jié),每k個字節(jié)的讀或寫操作完成,則將文件讀寫指針加k。事實上,有許多應用不再要求文件內再區(qū)分記錄,因而,為了簡化系統(tǒng),大多數(shù)現(xiàn)代操作系統(tǒng)如Linux系統(tǒng)只提供流式文件。(2)記錄式文件這是一種有結構的文件,它包含若干邏輯記錄,邏輯記錄是文件中按信息在邏輯上的獨立含義所劃分的信息單位,記錄在文件中的排列按其出現(xiàn)次序編號,記錄0,記錄1……。記錄式文件中有兩種常用的記錄組織和使用方法:①記錄式順序文件:文件的記錄順序生成并被順序訪問。②記錄式索引順序文件:這種文件使用索引表,表項包含記錄鍵和索引指針,記錄鍵有應用程序確定,而索引指針便指向相應記錄。這種文件可針對特定記錄進行存取,它也保持著順序訪問記錄的功能。2.文件物理結構(1)順序文件 將文件中邏輯上連續(xù)的信息存放到存儲介質的相鄰物理塊上形成順序結構,叫做順序文件,又稱連續(xù)文件。這種文件結構的優(yōu)點是管理簡單,存取速度快。主要缺點是建立文件之前需預先確定文件長度,以便分配存儲空間;修改、插入和添加文件記錄有一定的難度;對于變長記錄的處理很困難;對磁盤做連續(xù)分配會造成空閑塊的浪費。(2)連接文件。把邏輯文件中各個邏輯記錄存放到一些磁盤塊中,這些磁盤塊可以是不連續(xù)的,用指針把這些磁盤塊按邏輯記錄的順序連接起來,形成了文件的連接結構。文件信息存放在磁盤的若干物理塊中,第一塊文件信息的物理地址由FCB給出,而每塊的連接字出文件的下一個物理塊位置。通常,當連接字的內容為0時,表示文件至本塊結束。連接文件結構的優(yōu)點是易于文件擴充,不要求占用連續(xù)的外存空間,存儲空間利用率高。由于連接文件只能按連接指針順序搜索,因此存取速度慢。(3)索引文件索引結構是實現(xiàn)非連續(xù)存儲的另一種方法,適用于數(shù)據(jù)記錄保存在磁盤上的文件,系統(tǒng)為每個文件建立索引表(indextable),可以有不同的索引形式,一種是記錄組成文件的磁盤塊號,這種索引表只是磁盤塊號的序列,適用于流式文件;另一種其索引表項包含記錄鍵及其磁盤塊號,適用于記錄式文件。利用索引表來搜索記錄的文件稱為索引文件,索引表可存放在FCB中,打開文件時就可使用索引表訪問文件信息,大文件的索引表很大。有些文件系統(tǒng)讓索引表置于單獨的物理塊中且可駐留在磁盤上,F(xiàn)CB中僅包含索引表的地址。索引文件結構既可滿足文件動態(tài)增、刪的要求,存儲空間的利用率也較高;索引結構既適用于順序存取,也適用于隨機存取,可以方便、較迅速地實現(xiàn)文件的存取。缺點是由于使用索引表而增加了存儲空間的開銷。文件系統(tǒng)的接口文件系統(tǒng)作為一個高效管理文件的程序,其運行更多的是在系統(tǒng)內部運行,而用戶所需要關心只是它的接口。文件系統(tǒng)通常向用戶提供以下兩類接口。第一類是與文件有關的操作命令或者作業(yè)控制語言中與文件有關的語句,構成文件系統(tǒng)命令接口;第二類是提供給用戶程序使用的文件系統(tǒng)調用,構成了用戶和文件系統(tǒng)的另一個接口,稱為程序接口。文件系統(tǒng)提供給用戶程序的一組系統(tǒng)調用,包括建立、打開、關閉、撤銷、讀、寫和控制。通過這些系統(tǒng)調用,用戶可以獲得文件系統(tǒng)的各種服務。基本文件系統(tǒng)調用有建立文件、打開文件、讀寫文件、關閉文件等。文件系統(tǒng)模擬實現(xiàn)實驗內容編寫程序模擬一個簡單的文件系統(tǒng),具體實驗內容如下:(1)實現(xiàn)多級目錄結構,而非二級目錄結構。(2)實現(xiàn)文件和目錄的創(chuàng)建、刪除、重命名和讀寫權限控制功能。(3)實現(xiàn)顯示文件內容和更改文件內容的功能。(4)創(chuàng)建文件或目錄時,采用動態(tài)申請的方式請求存儲空間分配,在刪除文件或目錄時,還需對申請的空間進行釋放。(5)為觀察各種命令執(zhí)行情況,要求以樹形結構直觀地顯示命令執(zhí)行后的目錄結構。實驗指導1.主要數(shù)據(jù)結構說明(1)文件控制塊(FCB)應包含:文件名、文件內容、父目錄地址、同級目錄文件地址、讀寫權限等信息。其數(shù)據(jù)結構及說明如下:typedefstructFILE { charname[256]; //文件名 charcontent[1000]; //文件內容 structFILE*frontFile; //同級目錄上一文件 structFILE*nextFile; //同級目錄下一文件 structFOLDER*parentFolder; //父目錄 intcanRead; //是否可讀 intcanWrite; //是否可寫}FILE,*PFILE;(2)目錄結構typedefstructFOLDER { charname[256]; //目錄名 structFOLDER*nextFolder; //同級下一目錄 structFOLDER*frontFolder; //同級上一目錄 structFOLDER*parentFolder; //父目錄 structFOLDER*firstChildFolder;//子目錄 structFILE*firstChildFile; //子文件 intcanRead; //是否可讀 intcanWrite; //是否可寫}FOLDER,*PFOLDER;(3)在模擬程序中,應先建立文件系統(tǒng)的根目錄,文件系統(tǒng)中的操作都在此目錄下完成,且不得直接對根目錄操作。PFOLDERroot; //根目錄(4)在指定目錄下新建立的文件和目錄,都通過該目錄中最后一個子文件或子目錄的nextFile或nextFolder指針建立連接;若該目錄之中無任何子文件和子目錄,則通過該目錄的firstChildFolder(或firstChildFile)指針建立連接。如圖8.2所示。圖8.2多級目錄結構2.文件系統(tǒng)模擬程序執(zhí)行流程(1)程序運行時,系統(tǒng)首先根據(jù)目錄FOLDER結構建立根目錄root,并為其分配空間,初始化其信息。(2)程序給出一個菜單,用戶根據(jù)菜單選項前的數(shù)字,選擇要執(zhí)行的操作命令。(3)若在根目錄下建立子目錄,則建立一個新FOLDER并為其分配空間后,利用根目錄中的子目錄節(jié)點指針與該子目錄建立連接。(4)若在根目錄下建立文件,則建立一個新FCB并為其分配空間后,利用根目錄中的子文件節(jié)點指針與該文件建立連接。(5)對指定文件或目錄進行刪除、重命名、設置權限等操作時,需要先在文件系統(tǒng)中找到目標文件或目錄才可進行下一步的操作,否則提示用戶目標文件或目錄不存在。(6)若文件或目錄若不具有可讀權限,不會在文件系統(tǒng)中顯示,處于隱藏狀態(tài),但并不代表不存在;文件或目錄若不具有可寫權限,則不能對在該目錄下執(zhí)行創(chuàng)建,刪除,不能重命名該目錄;不能更改文件內容。(7)每次執(zhí)行操作命令后,為直觀地觀察執(zhí)行情況,會顯示輸出命令執(zhí)行后的目錄結構。文件系統(tǒng)執(zhí)行流程如圖8.3所示。圖8.3文件系統(tǒng)執(zhí)行流程3.各種操作命令流程圖本實驗模擬實現(xiàn)多個目錄和文操作命令,這里給出其中部分操作命令的流程圖。創(chuàng)建目錄、刪除目錄、重命名目錄、更改目錄權限和更改文件內容的流程圖如圖8.6——圖8.10所示。圖8.6創(chuàng)建目錄流程圖圖8.7刪除目錄流程圖圖8.8重命名目錄流程圖圖8.9更改目錄權限流程圖圖8.10更改文件內容流程圖程序示例#include"stdio.h"#include"string.h"#include"stdlib.h"typedefstructFOLDER //目錄結構{ charname[256]; //目錄名 structFOLDER*nextFolder; //同級下一目錄 structFOLDER*frontFolder; //同級上一目錄 structFOLDER*parentFolder; //父目錄 structFOLDER*firstChildFolder;//子目錄 structFILE*firstChildFile; //子文件 intcanRead; //是否可讀 intcanWrite; //是否可寫}FOLDER,*PFOLDER;typedefstructFILE //文件控制塊信息{ charname[256]; //文件名 charcontent[1000]; //文件內容 structFILE*frontFile; //同級目錄上一文件 structFILE*nextFile; //同級目錄下一文件 structFOLDER*parentFolder; //父目錄 intcanRead; //是否可讀 intcanWrite; //是否可寫}FILE,*PFILE;PFOLDERroot; //根目錄intcount=0; //控制輸出格式intflagD=0; //刪除標記PFOLDERfindCurrentFolder(PFOLDERcurrentFolder,charname[]) //查找指定目錄{ PFOLDERfolder; if(currentFolder==NULL) returnNULL; //沒找到 if(strcmp(currentFolder->name,name)==0) returncurrentFolder; //查找目錄為當前目錄 folder=findCurrentFolder(currentFolder->firstChildFolder,name); if(folder!=NULL) returnfolder; //查找目錄在子目錄中 folder=findCurrentFolder(currentFolder->nextFolder,name); if(folder!=NULL) returnfolder; //查找目錄在同級其它目錄中 returnNULL; //沒找到}PFILEfindCurrentFile(PFOLDERcurrentFolder,charname[])//查找指定文件{ PFILEtempFile; if(currentFolder==NULL) returnNULL; //沒找到 tempFile=currentFolder->firstChildFile; while(tempFile!=NULL) //遍歷當前目錄子文件 { if(strcmp(tempFile->name,name)==0) returntempFile; //找到了 tempFile=tempFile->nextFile; } tempFile=findCurrentFile(currentFolder->firstChildFolder,name); if(tempFile!=NULL) returntempFile; //查找文件在子目錄中 tempFile=findCurrentFile(currentFolder->nextFolder,name); if(tempFile!=NULL) returntempFile; //查找文件在同級其它目錄中 returnNULL; //沒找到}PFOLDERprepareWorkBeforeCreate() { PFOLDERcurrentFolder=NULL; charname[256]; printf("輸入當前目錄名稱:"); gets(name); fflush(stdin); currentFolder=findCurrentFolder(root,name); if(currentFolder==NULL) { puts("目錄不存在!"); returnNULL; } if(currentFolder->canWrite==0) { puts("權限不夠,不予創(chuàng)建!"); returnNULL; } returncurrentFolder;}voidcreateFolder() //當前目錄中創(chuàng)建新目錄{ PFOLDERcurrentFolder=prepareWorkBeforeCreate(); if(currentFolder==NULL){ //目標目錄不存在 return; } charname[256]; printf("輸入新目錄名稱:"); gets(name); fflush(stdin); PFOLDERnewFolder; newFolder=(PFOLDER)malloc(sizeof(FOLDER)); strcpy(newFolder->name,name); newFolder->firstChildFolder=NULL; //初始化新目錄 newFolder->firstChildFile=NULL; newFolder->nextFolder=NULL; newFolder->parentFolder=NULL; newFolder->frontFolder=NULL; newFolder->canRead=1; newFolder->canWrite=1; if(currentFolder->firstChildFolder==NULL) //當前目錄下無子目錄 { currentFolder->firstChildFolder=newFolder; newFolder->parentFolder=currentFolder; } else //當前目錄下有子目錄 { PFOLDERtempFolder=currentFolder->firstChildFolder; PFOLDERlastFolder; //保存當前currentFolder下最后一個子folder while(tempFolder!=NULL) //同級目錄下不得有相同目錄 { lastFolder=tempFolder; if(strcmp(tempFolder->name,newFolder->name)==0) { printf("%s目錄下已有同名目錄!\n",currentFolder->name); free(newFolder); return; } tempFolder=tempFolder->nextFolder; } lastFolder->nextFolder=newFolder; //將新目錄與同級舊目錄建立連接 newFolder->frontFolder=lastFolder; } puts("創(chuàng)建成功!");}voidcreateFile() //當前目錄中創(chuàng)建新文件{ PFOLDERcurrentFolder=prepareWorkBeforeCreate(); if(currentFolder==NULL){ //目標目錄不存在 return; } charname[256]; printf("輸入新文件名稱:"); gets(name); fflush(stdin); PFILEnewFile; newFile=(PFILE)malloc(sizeof(FILE)); strcpy(newFile->name,name); printf("是否輸入文件內容?"); charans=getchar(); fflush(stdin); if(ans=='y'||ans=='Y') { printf("輸入文件內容:"); gets(newFile->content); } else { strcpy(newFile->content,""); } fflush(stdin); newFile->nextFile=NULL; //初始化新文件信息 newFile->frontFile=NULL; newFile->parentFolder=NULL; newFile->canRead=1; newFile->canWrite=1; if(currentFolder->firstChildFile==NULL) //當前目錄下無子文件 { currentFolder->firstChildFile=newFile; newFile->parentFolder=currentFolder; } else //當前目錄下有子文件 { PFILEtempFile=currentFolder->firstChildFile; PFILElastFile; //保存當前currentFolder下最后一個子file while(tempFile!=NULL) //同級目錄下不得有相同文件 { lastFile=tempFile; if(strcmp(tempFile->name,newFile->name)==0) { printf("%s目錄下已有同名文件!\n",currentFolder->name); free(newFile); return; } tempFile=tempFile->nextFile; } lastFile->nextFile=newFile; //將新文件與同級文件建立連接 newFile->frontFile=lastFile; } puts("創(chuàng)建成功!");}voidinputName(charname[]){ printf("輸入名稱:"); gets(name); fflush(stdin);}voiddeleteAllChild(PFOLDERcurrentFolder) //刪除該目錄下所有內容{ PFILEtempFile,dFile; if(currentFolder==NULL) return; if(flagD) deleteAllChild(currentFolder->nextFolder); flagD=1; deleteAllChild(currentFolder->firstChildFolder);//遍歷子目錄 tempFile=currentFolder->firstChildFile; while(tempFile!=NULL) //刪除該目錄子文件 { dFile=tempFile; tempFile=tempFile->nextFile; free(dFile); //(釋放空間) } free(currentFolder); //刪除該目錄(釋放空間)}voiddeleteFolder() //刪除目錄所有內容{ charname[256]; inputName(name); if(strcmp(name,"root")==0) { puts("根目錄不準刪除!"); return; } PFOLDERcurrentFolder=findCurrentFolder(root,name); if(currentFolder==NULL) { printf("目錄不存在!"); return; } if(currentFolder->canWrite==0) { puts("權限不夠,不予刪除!"); return; } if(currentFolder->frontFolder==NULL) { currentFolder->parentFolder->firstChildFolder=currentFolder->nextFolder; //斷開連接 if(currentFolder->nextFolder!=NULL) //重設為頭 currentFolder->nextFolder->frontFolder=NULL; } else currentFolder->frontFolder->nextFolder=currentFolder->nextFolder; //斷開連接 deleteAllChild(currentFolder); //(釋放空間) puts("刪除成功!");}voiddeleteFile() //刪除文件{ charname[256]; inputName(name); PFILEcurrentFile=findCurrentFile(root,name); if(currentFile==NULL) { printf("文件不存在!"); return; } if(currentFile->frontFile==NULL) { currentFile->parentFolder->firstChildFile=currentFile->nextFile; //斷開連接 if(currentFile->nextFile!=NULL) currentFile->nextFile->frontFile=NULL; //重設為頭 } else currentFile->frontFile->nextFile=currentFile->nextFile; //斷開連接 free(currentFile); //刪除文件 puts("刪除成功!");}voiddisplayFileSystemStructure(PFOLDERcurrentFolder) //輸出目錄結構{ PFILEtempFile; if(currentFolder!=NULL&¤tFolder->canRead) //是否可讀 { for(inti=0;i<count;i++) printf(""); printf("|-"); printf(currentFolder->name); intlength=15-count*2-strlen(currentFolder->name); for(i=0;i<length;i++) //權限 printf(""); if(count==0) printf("canReadcanWrite\n"); else printf("<dir>%d%d\n",currentFolder->canRead,currentFolder->canWrite); } elseif(currentFolder==NULL) { count--; return; } count++; tempFile=currentFolder->firstChildFile; while(tempFile!=NULL) //遍歷子文件 { if(tempFile->canRead==1) //是否可讀 { for(inti=0;i<count;i++) printf(""); printf("|-"); printf(tempFile->name); intlength=20-count*2-strlen(tempFile->name); for(i=0;i<length;i++) //權限 printf(""); if(count==0) printf("canReadcanWrite\n"); else printf("%d%d\n",tempFile->canRead,tempFile->canWrite); } tempFile=tempFile->nextFile; } displayFileSystemStructure(currentFolder->firstChildFolder); //遍歷子目錄 displayFileSystemStructure(currentFolder->nextFolder); //遍歷同級目錄}voidshowFileContent() //顯示文件內容{ PFILEcurrentFile=NULL; charname[256]; printf("輸入文件名:"); gets(name); fflush(stdin); currentFile=findCurrentFile(root,name); if(currentFile==NULL) { puts("文件不存在!"); return; } if(!currentFile->canRead) { puts("權限不夠,無法讀?。?); return; } printf("文件內容:%s\n",currentFile->content); printf("文件長度:%d\n",strlen(currentFile->content));}voidchangeFileContent() //更改文件內容{ PFILEcurrentFile=NULL; charname[256]; printf("輸入文件名:"); gets(name); fflush(stdin); currentFile=findCurrentFile(root,name); if(currentFile==NULL) { puts("文件不存在!"); return; } if(!currentFile->canWrite) { puts("權限不夠,不予修改!"); return; } printf("輸入文件內容:"); gets(currentFile->content); fflush(stdin); puts("更改成功!");}voidchangeAllChildPermission(PFOLDERcurrentFolder,intcanRead,intcanWrite) //更改子目錄下所有目錄和文件權限{ PFILEtempFile; if(currentFolder!=NULL) { currentFolder->canRead=canRead; currentFolder->canWrite=canWrite; } elseif(currentFolder==NULL) return; tempFile=currentFolder->firstChildFile; while(tempFile!=NULL) //遍歷子文件 { tempFile->canRead=canRead; tempFile->canWrite=canWrite; tempFile=tempFile->nextFile; } changeAllChildPermission(currentFolder->firstChildFolder,canRead,canWrite); //遍歷子目錄 if(currentFolder->firstChildFolder!=NULL) changeAllChildPermission(currentFolder->firstChildFolder->nextFolder,canRead,canWrite);//遍歷同級目錄}voidchangeFolderPermission() //更改目錄權限{ charname[256]; inputName(name); if(strcmp(name,"root")==0) { puts("根目錄不準更改權限!"); return; } PFOLDERcurrentFolder=NULL; currentFolder=findCurrentFolder(root,name); if(currentFolder==NULL) { puts("目錄不存在!"); return; } printf("輸入目錄權限(讀和寫):"); scanf("%d%d",¤tFolder->canRead,¤tFolder->canWrite); fflush(stdin); changeAllChildPermission(currentFolder,currentFolder->canRead,currentFolder->canWrite); //更改當前目錄權限時,同時更改其目錄下所有文件和目錄權限 puts("權限更改成功!");}voidchangeFilePermission() //更改文件權限{ charname[256]; inputName(name); PFILEcurrentFile=NULL; currentFile=findCurrentFile(root,name); if(currentFile==NULL) { puts("文件不存在!"); return; } printf("輸入文件權限(讀和寫)"); scanf("%d%d",¤tFile->canRead,¤tFile->canWrite); fflush(stdin); puts("權限更改成功!");}intfileNameIsDuplication(PFILEcurrentFile,charname[]) //判斷新重命名的文件是否重名{ PFILEtempFile=currentFile->frontFile; while(tempFile!=NULL) //向前掃描 { if(strcmp(tempFile->name,name)==0) { printf("文件重名!\n"); return1; } tempFile=tempFile->frontFile; } tempFile=currentFile->nextFile; while(tempFile!=NULL) //向后掃描 { if(strcmp(tempFile->name,name)==0) { printf("文件重名!\n"); return1; } tempFile=tempFile->nextFile; } return0;}intfolderNameIsDuplication(PFOLDERcurrentFolder,charname[]) //判斷新重命名的目錄是否重名{ PFOLDERtempFolder=currentFolder->frontFolder; while(tempFolder!=NULL) //向前掃描 { if(strcmp(tempFolder->name,name)==0) { printf("目錄重名!\n"); return1; } tempFolder=tempFolder->frontFolder; } tempFolder=currentFolder->nextFolder; while(tempFolder!=NULL) //向后掃描 { if(strcmp(tempFolder->name,name)==0) { printf("目錄重名!\n"); return1; } tempFolder=tempFolder->nextFolder; } return0;}voidrenameFolder() //重命名目錄{ charname[256]; inputName(name); if(strcmp("root",name)==0) { puts("根目錄不準更改!"); return; } PFOLDERcurrentFolder=findCurrentFolder(root,name); if(currentFolder==NULL) { puts("目錄不存在!"); return; } printf("輸入新名稱:"); gets(name); fflush(stdin); if(folderNameIsDuplication(currentFolder,name)) //重名 return; strcpy(currentFolder->name,name); puts("重命名成功!");}voidrenameFile() //重命名文件{ charname[256]; inputName(name); PFILEcurrentFile=findCurrentFile(root,name); if(currentFile==NULL) { puts("文件不存在!"); return; } printf("輸入新名稱:"); gets(name); fflush(stdin); if(fileNameIsDuplication(currentFile,name)) //重名 return; strcpy(currentFile->name,name); puts("重命名成功!");}voidmenu() //菜單{ intchoice; printf("\t************************\n"); printf("\t*1.創(chuàng)建目錄*\n"); printf("\t*2.刪除目錄*\n"); printf("\t*3.重命名目錄*\n"); printf("\t*4.更改目錄權限*\n"); printf("\t*5.創(chuàng)建文件*\n"); printf("\t*6.刪除文件*\n"); printf("\t*7.重命名文件*\n"); printf("\t*8.顯示文件內容*\n"); printf("\t*9.更改文件內容*\n"); printf("\t*10.更改文件權限*\n"); printf("\t*0.退出*\n"); printf("\t************************\n"); count=0; printf("\n目錄結構:\n"); displayFileSystemStructure(root); while(1) { printf("\n---------------------------------------------\n"); printf("請選擇操作命令:"); scanf("%d",&choice); fflush(stdin); switch(choice) { case1:createFolder(); //創(chuàng)建目錄 break; case2:deleteFolder(); //刪除目錄 break; case3: renameFolder(); //重命名目錄 break; case4: changeFolderPermission(); //更改目錄權限 break; case5:createFile(); //創(chuàng)建文件 break; case6:deleteFile(); //刪除文件 break; case7:renameFile(); //重命名文件 break; case8: showFileContent(); //顯示文件內容 break; case9: changeFileContent(); //更改文件內容 break; case10:changeFilePermission(); //更改文件權限 break; case0:exit(0); //退出 break; default:break; } count=0; printf("\n目錄結構:\n"); displayFileSystemStructure(root); }}voidinitRootFolder() //初始化根目錄信息{ root=(PFOLDER)malloc(sizeof(FOLDER)); root->frontFolder=NULL; root->nextFolder=NULL; root->parentFolder=NULL; root->firstChildFolder=NULL; root->firstChildFile=NULL; root->canRead=1; root->canWrite=1; strcpy(root->name,"root");}intmain(void){ initRootFolder(); menu(); return0;}運行結果及分析程序經(jīng)編譯運行后,文件模擬系統(tǒng)顯示一個菜單,并顯示樹形目錄,主界面如下所示:(1)主界面*************************1.創(chuàng)建目錄**2.刪除目錄**3.重命名目錄**4.更改目錄權限**5.創(chuàng)建文件**6.刪除文件**7.重命名文件**8.顯示文件內容**9.更改文件內容**10.更改文件權限**0.退出*************************目錄結構:|-rootcanReadcanWrite此時,用戶可選擇相應操作命令;在每一次完成操作后,會顯示目錄結構,便于用戶查看到文件系統(tǒng)內容的更新,從而了解命令的執(zhí)行情況。(2)創(chuàng)建目錄和創(chuàng)建文件當用戶選擇功能1后,首先需指定目標目錄,若目標目錄不存在或不具有可寫權限時,則會提示創(chuàng)建失敗,這時可更改目標目錄的可寫權限后繼續(xù)完成操作。目錄創(chuàng)建成功后,顯示新建立的目錄及其讀寫權限,為區(qū)別文件和目錄,在目錄名后輸出“<dir>”,表明這是一個子目錄。例如在root根目錄下建立子目錄folder1時,程序運行情況如下所示:---------------------------------------------請選擇操作命令:1輸入當前目錄名稱:root輸入新目錄名稱:folder1創(chuàng)建成功!目錄結構:|-rootcanReadcanWrite|-folder1<dir>11--------------------------------------------- 當用戶選擇功能5后將執(zhí)行創(chuàng)建文件操作。在創(chuàng)建文件時會提示用戶是否立刻輸入文件內容,若創(chuàng)建文件時并不想輸入內容,則可通過更改文件內容功能輸入文件內容,文件創(chuàng)建成功后,在目錄結構中顯示新文件及其讀寫權限,默認為可讀可寫,文件讀寫權限可執(zhí)行更改文件權限命令修改。例如在root根目錄下創(chuàng)建文件file.txt時,程序運行情況如下所示:---------------------------------------------請選擇操作命令:5輸入當前目錄名稱:root輸入新文件名稱:file.txt是否輸入文件內容?n創(chuàng)建成功!目錄結構:|-rootcanReadcanWrite|-file.txt11|-folder1<dir>11-----------------
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 工程施工合同詳細版
- 2025年阿壩貨運運輸駕駛員從業(yè)資格證考試試題
- 2025年煙臺經(jīng)營性道路客貨運輸駕駛員從業(yè)資格考試
- 2025年隴南貨運從業(yè)資格證在哪里練題
- 2025年淄博b2貨運資格證全題
- 《高血壓治療新進展》課件
- 第四單元 崇尚法治精神
- 水上救援車使用準則
- 科研機構鍋爐升級拆除合同
- 生物技術企業(yè)設計審查
- 《音樂學科課程標準與教材分析》課程教學大綱
- 英語培訓班招生宣傳海報
- DB32∕T 3690-2019 600MPa熱處理、熱軋帶肋鋼筋混凝土結構技術規(guī)程
- 風濕病概述及中國風濕病發(fā)展情況ppt
- 2021年食品安全監(jiān)督抽檢培訓完整版PPT課件
- 外研版(三起)小學英語四年級上冊教案(全冊)
- 部編二年級下冊語文詞語表帶拼音
- 檢測大綱-整車檢驗、過程檢驗、零部件入廠檢驗、關鍵部位檢驗、成品入庫檢驗
- 托輥技術規(guī)格書
- 踝關節(jié)扭傷.ppt
- CRH2型動車組一級檢修作業(yè)辦法081222
評論
0/150
提交評論