版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
文件系统实验实验目的和要求实验目的通常把文件与管理信息资源的管理程序的集合称为文件系统,它是操作系统中负责存取和管理信息资源的模块,采用统一的方法管理用户信息和系统信息的存储、检索、更新、共享和保护,并为用户提供一套行之有效的文件使用及操作方法。本实验利用高级语言编写程序模拟文件系统,了解文件系统的基本结构和文件的各种操作方法,加深理解文件系统的内部功能及内部实现,从而帮助学生对各种文件操作命令的实质内容和执行过程有比较深入的了解。实验要求1.采用高级语言编写程序模拟文件系统,文件系统采用多级目录结构,实现对文件和目录的创建、删除、重命名、变更权限、显示文件内容、修改文件内容等操作。2.撰写实验报告,报告应包含以下内容:(1)实验目的;(2)实验内容;(3)设计思路;(4)程序流程图;(5)程序中主要数据结构和函数说明;(6)带注释的源程序代码;(7)程序运行结果及分析(8)实验收获与体会预备知识文件和文件系统1.文件概念现代计算机系统中都配置了外存,大量的程序和数据以文件的形式存放在外存。如果由用户直接管理文件,不仅要求用户熟悉外存特性,了解各种文件的属性,以及它们在外存上的位置,而且多用户环境下还必须能保持数据的安全性和一致性,这是用户不能胜任的。因而,现代操作系统中都配备文件系统,以适应系统资源管理和用户使用信息的需要。文件是指由创建者所定义的、具有文件名的一组相关元素的集合。用户通过文件名就可对文件进行访问,文件名是由字母或数字组成的字母或数字串,其格式和长度都因系统而异。操作系统提供文件系统的优点有:(1)便于用户使用。(2)文件安全可靠。(3)系统能有效利用存储空间,优化安排不同属主文件的位置。(4)文件系统还能提供文件共享功能。2.文件命名在不同的操作系统中对文件名的规定有所不同,文件名的格式和长度因系统而异。一般来说,文件名由文件名和扩展名两部分组成,前者用于标识文件,后者用于区分文件类型,中间用“.”分割开来,它们都是字母或数字所组成的字母数字串。早期文件名的长度仅限1~8个字符,现在文件名最长可达255个字符。扩展名是添加在文件名后面的若干个附加字符,又称为后缀名,用于只是文件类型。例如,.txt指明纯文本文件,.exe表示可执行二进制代码文件,.obj表示编译或汇编生成的目标文件。3.文件类型 为便于管理和控制文件,将文件分为多种类型,下面是几种常用的文件分类方法。 (1)按用途分类:系统文件,库文件,用户文件。 (2)按存取控制属性分类:只读文件,读写文件,不保护文件。 (3)按信息流向:输入文件,输出文件,输入输出文件。 (4)按文件中数据的形式分类:源文件,目标文件,可执行文件。4.文件属性文件属性是指操作系统为文件配置的控制和管理信息,其目的是为方便系统和用户对文件的管理和使用,这组属性包括以下内容。(1)文件基本属性:文件名和扩展名、文件属性ID,文件所属组ID等。(2)文件类型属性:如普通文件、目录文件、系统文件、隐藏文件、设备文件等。也可按文件信息分为ASCII码文件、二进制码文件等。(3)文件保护属性:规定谁能够访问文件,以何种方式访问。常用的文件访问方式有可读、可写、可执行、可更新、可删除等;有的系统还为文件设置口令用作保护。(4)文件管理属性:如文件创建时间、最后访问时间、最后修改时间等。(5)文件控制属性:文件逻辑结构信息,如:记录键、记录类型、记录个数、记录长度、成组因子数等;文件物理结构信息,如:文件所在设备名、物理设备类型、记录存放的盘块号或文件信息首选盘块号,也可指出文件索引的位置等。 5.文件存取方法存取方法是指读写文件存储器上的物理记录的方法,由于文件类型不同,用户使用的要求也不同,因而需要操作系统提供多种存取方法来满足用户要求。常用的存取方法如下:(1)顺序存取。无论是无结构字节流文件还是有结构记录式文件,存取操作都在上次操作的基础上进行。顺序存取主要用于磁带文件,但也适用于磁盘上的顺序文件。(2)直接存取。又称随机存取,可以非顺序的从文件中的任何位置存取文件内容。它通常用于磁盘文件。(3)索引存取。这是基于索引文件的存取方法,由于文件中的记录不按位置而是按其记录名或记录键来编址,所以用户提供记录名或记录键之后,先按名搜索,再查找所需要的记录。在实际系统中,大都采用多级索引以加速记录的查找过程。6.文件系统文件系统是操作系统中负责管理和存取文件的程序模块。它是由管理文件所需的数据结构和相应的管理软件以及访问文件的一组操作所组成。文件目录为了对文件实施有效的管理,必须对它们加以妥善组织,这主要是通过文件目录实现的。对目录管理的要求如下:实现“按名存取”提高对目录的检索速度。实现文件共享允许文件重名1.文件控制块文件控制块(FileControlBlock,FCB)是操作系统为每个文件建立的唯一数据结构,其中包括了全部文件属性,其目的是为了方便操作系统对文件的管理、控制和存取。于是一个文件有两部分组成:FCB和文件体(文件信息)。有了FCB就可以方便的实现文件的按名存取。每当创建一个文件时,系统就要为其建立一个FCB,用来记录文件的属性信息;每当存取文件时,先找到其FCB,再找到文件信息盘块号、首块物理位置或索引表就能存取文件信息。2.一级目录结构目录结构的组织关系到文件系统的存取速度,也关系到文件的共享性和安全性。因此组织好文件的目录,是设计好文件系统的重要环节。最简单的文件目录是一级目录结构,所有FCB排列在一张线性表中。一级目录的优点是简单,但它只能实现目录管理中最基本的按名存取功能,文件重名和文件共享问题难以解决。3.两级目录结构两级目录结构将文件目录分成主文件目录和用户文件目录两级。系统为每个用户建立一个用户文件目录(UFD),每个用户的文件目录登记了该用户建立的所有文件名及其属性信息。主目录(MFD)则登记了进入系统的各个用户文件目录的情况,每个用户占一个表目,说明该用户目录的属性,包括用户名、目录大小、组织形式及其所在的位置等。两级目录结构提高了目录检索的速度;允许不同的用户目录中使用相同的文件名;不同用户也可以使用不同的文件名或相同的文件名来访问系统中的同一个共享文件。两级目录结构虽然比较简单实用,但缺乏灵活性,特别是难以反映现实世界的多层次关系。4.多级树形目录结构在现代操作系统中,所有文件系统都支持多级目录结构,根目录是唯一的,每一级目录可以是下一级目录的说明,也可以是文件的说明,从而形成树状目录结构。如图8.1是Linux目录层次结构,它是一棵倒置的有根树,树根是根目录,从根向下,每个树枝是子目录,而树叶是文件。树状多级目录结构有许多优点,可以较好地反映现实世界中具有层次关系的数据结合,确切地反映系统内部文件的分支结构;不同文件可以重名,只要它们不位于同一末端子目录中即可;易于规定不同层次或子目录中文件的不同存取权限,便于文件的保护、保密和共享等,有利于系统的维护和查找。图8.1Linux目录层次结构文件结构在系统中的所有文件都存在着以下两种形式的文件结构:文件的逻辑结构。这是从用户观点出发所观察到的文件组织形式,即文件是由一系列的逻辑记录组成的,是用户可以直接处理的数据及其结构,它独立于文件的物理特性。文件的物理结构。这是指系统将文件存储在外存上所形成的一种存储组织形式,是用户不能看见的。文件的物理结构不仅与存储介质的存储性能有关,而且与所采用的外存分配方式有关。文件逻辑结构文件的逻辑结构分为两种形式:流式文件和记录式文件。(1)流式文件这是一种无结构的文件,文件内的数据不再组成纪录,只是一串顺序的信息集合,称为字节流文件。流式文件中的每个字节都有一个索引,第一个字节的索引为0,第二个字节的索引为1……打开文件的进程使用文件读写指针来访问文件中的特定字节。当文件打开时,文件读写指针指向首字节,每k个字节的读或写操作完成,则将文件读写指针加k。事实上,有许多应用不再要求文件内再区分记录,因而,为了简化系统,大多数现代操作系统如Linux系统只提供流式文件。(2)记录式文件这是一种有结构的文件,它包含若干逻辑记录,逻辑记录是文件中按信息在逻辑上的独立含义所划分的信息单位,记录在文件中的排列按其出现次序编号,记录0,记录1……。记录式文件中有两种常用的记录组织和使用方法:①记录式顺序文件:文件的记录顺序生成并被顺序访问。②记录式索引顺序文件:这种文件使用索引表,表项包含记录键和索引指针,记录键有应用程序确定,而索引指针便指向相应记录。这种文件可针对特定记录进行存取,它也保持着顺序访问记录的功能。2.文件物理结构(1)顺序文件 将文件中逻辑上连续的信息存放到存储介质的相邻物理块上形成顺序结构,叫做顺序文件,又称连续文件。这种文件结构的优点是管理简单,存取速度快。主要缺点是建立文件之前需预先确定文件长度,以便分配存储空间;修改、插入和添加文件记录有一定的难度;对于变长记录的处理很困难;对磁盘做连续分配会造成空闲块的浪费。(2)连接文件。把逻辑文件中各个逻辑记录存放到一些磁盘块中,这些磁盘块可以是不连续的,用指针把这些磁盘块按逻辑记录的顺序连接起来,形成了文件的连接结构。文件信息存放在磁盘的若干物理块中,第一块文件信息的物理地址由FCB给出,而每块的连接字出文件的下一个物理块位置。通常,当连接字的内容为0时,表示文件至本块结束。连接文件结构的优点是易于文件扩充,不要求占用连续的外存空间,存储空间利用率高。由于连接文件只能按连接指针顺序搜索,因此存取速度慢。(3)索引文件索引结构是实现非连续存储的另一种方法,适用于数据记录保存在磁盘上的文件,系统为每个文件建立索引表(indextable),可以有不同的索引形式,一种是记录组成文件的磁盘块号,这种索引表只是磁盘块号的序列,适用于流式文件;另一种其索引表项包含记录键及其磁盘块号,适用于记录式文件。利用索引表来搜索记录的文件称为索引文件,索引表可存放在FCB中,打开文件时就可使用索引表访问文件信息,大文件的索引表很大。有些文件系统让索引表置于单独的物理块中且可驻留在磁盘上,FCB中仅包含索引表的地址。索引文件结构既可满足文件动态增、删的要求,存储空间的利用率也较高;索引结构既适用于顺序存取,也适用于随机存取,可以方便、较迅速地实现文件的存取。缺点是由于使用索引表而增加了存储空间的开销。文件系统的接口文件系统作为一个高效管理文件的程序,其运行更多的是在系统内部运行,而用户所需要关心只是它的接口。文件系统通常向用户提供以下两类接口。第一类是与文件有关的操作命令或者作业控制语言中与文件有关的语句,构成文件系统命令接口;第二类是提供给用户程序使用的文件系统调用,构成了用户和文件系统的另一个接口,称为程序接口。文件系统提供给用户程序的一组系统调用,包括建立、打开、关闭、撤销、读、写和控制。通过这些系统调用,用户可以获得文件系统的各种服务。基本文件系统调用有建立文件、打开文件、读写文件、关闭文件等。文件系统模拟实现实验内容编写程序模拟一个简单的文件系统,具体实验内容如下:(1)实现多级目录结构,而非二级目录结构。(2)实现文件和目录的创建、删除、重命名和读写权限控制功能。(3)实现显示文件内容和更改文件内容的功能。(4)创建文件或目录时,采用动态申请的方式请求存储空间分配,在删除文件或目录时,还需对申请的空间进行释放。(5)为观察各种命令执行情况,要求以树形结构直观地显示命令执行后的目录结构。实验指导1.主要数据结构说明(1)文件控制块(FCB)应包含:文件名、文件内容、父目录地址、同级目录文件地址、读写权限等信息。其数据结构及说明如下: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)在模拟程序中,应先建立文件系统的根目录,文件系统中的操作都在此目录下完成,且不得直接对根目录操作。PFOLDERroot; //根目录(4)在指定目录下新建立的文件和目录,都通过该目录中最后一个子文件或子目录的nextFile或nextFolder指针建立连接;若该目录之中无任何子文件和子目录,则通过该目录的firstChildFolder(或firstChildFile)指针建立连接。如图8.2所示。图8.2多级目录结构2.文件系统模拟程序执行流程(1)程序运行时,系统首先根据目录FOLDER结构建立根目录root,并为其分配空间,初始化其信息。(2)程序给出一个菜单,用户根据菜单选项前的数字,选择要执行的操作命令。(3)若在根目录下建立子目录,则建立一个新FOLDER并为其分配空间后,利用根目录中的子目录节点指针与该子目录建立连接。(4)若在根目录下建立文件,则建立一个新FCB并为其分配空间后,利用根目录中的子文件节点指针与该文件建立连接。(5)对指定文件或目录进行删除、重命名、设置权限等操作时,需要先在文件系统中找到目标文件或目录才可进行下一步的操作,否则提示用户目标文件或目录不存在。(6)若文件或目录若不具有可读权限,不会在文件系统中显示,处于隐藏状态,但并不代表不存在;文件或目录若不具有可写权限,则不能对在该目录下执行创建,删除,不能重命名该目录;不能更改文件内容。(7)每次执行操作命令后,为直观地观察执行情况,会显示输出命令执行后的目录结构。文件系统执行流程如图8.3所示。图8.3文件系统执行流程3.各种操作命令流程图本实验模拟实现多个目录和文操作命令,这里给出其中部分操作命令的流程图。创建目录、删除目录、重命名目录、更改目录权限和更改文件内容的流程图如图8.6——图8.10所示。图8.6创建目录流程图图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("权限不够,不予创建!"); returnNULL; } returncurrentFolder;}voidcreateFolder() //当前目录中创建新目录{ 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("创建成功!");}voidcreateFile() //当前目录中创建新文件{ 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("创建成功!");}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.创建目录*\n"); printf("\t*2.删除目录*\n"); printf("\t*3.重命名目录*\n"); printf("\t*4.更改目录权限*\n"); printf("\t*5.创建文件*\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(); //创建目录 break; case2:deleteFolder(); //删除目录 break; case3: renameFolder(); //重命名目录 break; case4: changeFolderPermission(); //更改目录权限 break; case5:createFile(); //创建文件 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;}运行结果及分析程序经编译运行后,文件模拟系统显示一个菜单,并显示树形目录,主界面如下所示:(1)主界面*************************1.创建目录**2.删除目录**3.重命名目录**4.更改目录权限**5.创建文件**6.删除文件**7.重命名文件**8.显示文件内容**9.更改文件内容**10.更改文件权限**0.退出*************************目录结构:|-rootcanReadcanWrite此时,用户可选择相应操作命令;在每一次完成操作后,会显示目录结构,便于用户查看到文件系统内容的更新,从而了解命令的执行情况。(2)创建目录和创建文件当用户选择功能1后,首先需指定目标目录,若目标目录不存在或不具有可写权限时,则会提示创建失败,这时可更改目标目录的可写权限后继续完成操作。目录创建成功后,显示新建立的目录及其读写权限,为区别文件和目录,在目录名后输出“<dir>”,表明这是一个子目录。例如在root根目录下建立子目录folder1时,程序运行情况如下所示:---------------------------------------------请选择操作命令:1输入当前目录名称:root输入新目录名称:folder1创建成功!目录结构:|-rootcanReadcanWrite|-folder1<dir>11--------------------------------------------- 当用户选择功能5后将执行创建文件操作。在创建文件时会提示用户是否立刻输入文件内容,若创建文件时并不想输入内容,则可通过更改文件内容功能输入文件内容,文件创建成功后,在目录结构中显示新文件及其读写权限,默认为可读可写,文件读写权限可执行更改文件权限命令修改。例如在root根目录下创建文件file.txt时,程序运行情况如下所示:---------------------------------------------请选择操作命令:5输入当前目录名称:root输入新文件名称:file.txt是否输入文件内容?n创建成功!目录结构:|-rootcanReadcanWrite|-file.txt11|-folder1<dir>11-----------------
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 装修补充协议
- 投资入股协议书集合
- 泌尿系统疾病临床诊疗技术(内科学课件)
- 2024年度农用三轮车技术支持与服务合同3篇
- 全新赠与赠予协议书下载3篇
- 2024至2030年中国免消毒液洗衣粉行业投资前景及策略咨询研究报告
- 教育心理学2024课件详细解析
- 幼儿园卫生消毒培训:2024年我国现状与挑战
- 基于2024年度销售目标的电商合伙合同2篇
- 个人向单位借款合同范本2024版
- 中医学阴阳五行(课堂PPT)
- 第六章缝隙天线及微带天线
- 管道探伤焊口计算表
- 江苏定额站对定额疑问的解答
- 室外照明设计规范说明WORD
- 1000字作文稿纸模板(完美版)
- 【校本教材】《身边的化学》高中化学校本课程
- 小学六年级健康教育《轻度损伤的自我处理》优质课教学设计
- 渠道混凝土衬砌方案
- 初一上册整式化简求值60题(含答案)
- 浅谈隧道混凝土衬砌裂缝的成因及处理
评论
0/150
提交评论