操作系统课程设计简单文件系统的实现
- 格式:docx
- 大小:25.18 KB
- 文档页数:10
《操作系统》课程设计题目:设计一个简单二级文件系统专业:计算机科学与技术年级:文计091-1*名:***学号:200990514103指导教师:任满杰时间:2011-2012第二学期2012年9月1日一、设计内容1、可以实现下列几条命令。
Format 格式化Dir 列文件目录Create 创建文件Delete 删除文件Deldir 删除目录Open 打开文件Close 关闭文件Search 查询文件Copy 拷贝文件Cut 剪切文件二、开发环境Windows操作系统Microsoft Visual C++三、分析设计(一)实验原理通过程序模拟Linux文件系统,用一个二进制文件(FileSystem.disk)来模拟磁盘.设计一个多用户的二级文件系经统、实现一般的创建文件、目录,删除文件、目录,切换目录,打开、关闭文件、读写文件等操作。
文件系统,包含格式化,显示文件(目录),创建文件等几个简单命令的实现,而且能完成超级块的读写,节点的读写等过程. 本文件系统采用两级目录,其中第一级对应于用户账号,第二级对应于用户账号下的文件。
另外,为了简单本文件系统未考虑文件共享、文件系统安全以及管道文件与设备文件等特殊内容。
1.程序执行流程图:2.数据块的分配和回收(二)程序结构设计FileSystem类负责管理磁盘空间和磁盘内存I节点,负责对磁盘空间和磁盘数据进行优化管理。
并提代接口言方法供用户或程序调用。
(三)数据结构int physic[100]; //文件地址缓冲区int style=1; //文件的类型char cur_dir[10]="root"; //当前目录int search_i=0;struct command{char com[10];}cmd[20];struct block{int n; //空闲的盘快的个数int free[50]; //存放空闲盘快的地址int a; //模拟盘快是否被占用}memory[20449];struct block_super{int n; //空闲的盘快的个数int free[50]; //存放进入栈中的空闲块int stack[50]; //存放下一组空闲盘快的地址}super_block;struct node //i结点信息{int file_style; //i结点文件类型int file_length; //i结点文件长度int file_address[100]; //i结点文件的物理地址 char file_message[100];} i_node[640];struct dir //目录项信息{char file_name[10]; //文件名int i_num; //文件的结点号char dir_name[10]; //文件所在的目录} root[640];四.运行示例及结果分析菜单删除目录文件查询拷贝剪切五、程序实现详细程序请参见源文件, 在此只列举3点1、剪切文件程序片段:void cut(char *tmp,char *newname) {int i; //,jchar t[20];_strtime(t);for(i=0;i<640;i++)if(strcmp(newname,root[i].file_name)==0){break;}if(i==640){printf("目录不存在,不能剪切!\n");return;}for(i=0;i<640;i++){if(strcmp(tmp,root[i].file_name)==0){strcpy(root[i].dir_name,newname);strcpy(i_node[root[i].i_num].change_t,t);//printf("剪切成功!\n");//return;}}if(i==640)printf("文件不存在,执行失败!\n");}2.无文件查询程序片段:void search(char* filename){int sign=0;for(search_i=0;search_i<640;search_i++){if(strcmp(root[search_i].file_name,filename)==0) //查询文件中所在目录信息和当前目录信息相同的数据{sign=1;int k=root[search_i].i_num;printf("%s\t",root[search_i].file_name); //文件名printf(" %d\t",i_node[k].file_style); //文件的类型printf(" %d\t\t",i_node[k].file_length); //文件的长度printf("%s\n",root[search_i].dir_name); //文件所在的目录}}if (sign==0){printf("%s\n","未找到该文件!");}}六、心得与体会这次设计中遇到最难的问题就是拷贝功能的实现,由于之前没有接触过拷贝的原理,所以通过和同伴的讨论和试验,终于突发奇想的运用改变文件路径的源代码和创建文件相结合,终于实现了拷贝功能,能够将一个文件从一个目录拷贝到另一目录(即先移动过去然后再在原位置创建一个原文件),可是却无法拷贝到root根目录,为了解决这个问题,又在创建文件的程序里添加了一个判断是否为根目录的语句,可是后来又发现了真个系统存在重命名的问题。
目录一、课程设计题目和目的 (1)二、课程设计要求 (1)三、程序设计思想 (1)四、文件系统的实现 (1)1.数据结构设计 (1)2.程序功能图 (2)3.实体关系图 (3)4.数据流图.................................................. 错误!未定义书签。
5.程序流程图 (3)(1) .建立文件:create(文件名,记录长度) (4)(2) .写文件:write(文件名,开始位置,字符串) (5)(3) .读文件:read(文件名,开始位置,长度) (6)(4) .显示文件所有内容 type(文件名) ....................... 错误!未定义书签。
(5) .删除文件delete(文件名) .............................. 错误!未定义书签。
(6) .重命名文件ren(文件名,新文件名) ..................... 错误!未定义书签。
(7) .查询文件属性ask(文件名) ............................. 错误!未定义书签。
(8) .关闭文件close(文件名) ............................... 错误!未定义书签。
五、程序运行结果及分析 (8)六、课程设计总结 (10)七、参考文献 (11)八、附录 (12)一、课程设计题目和目的通过模拟文件系统的实现,深入理解操作系统中文件系统的理论知识, 加深对教材中的重要算法的理解。
同时通过编程实现这些算法,更好地掌握操作系统的原理及实现方法,提高综合运用各专业课知识的能力。
二、课程设计要求通过组长分工,我主要完成了如下几个功能的操作:1.创建文件:从命令中得到文件名,得到该文件的文件长度,建立文件。
修改目录表。
4.读文件:read [文件名] [显示开始字节] [显示的字节数] ,直接显示所需要的字节数。
操作系统的文件系统设计与实现在计算机系统中,文件系统是操作系统中的一个重要组成部分,用于管理和组织存储在磁盘或其他存储介质中的文件。
一个良好设计且高效实现的文件系统可以提供可靠的数据存储和高速的数据访问,并确保文件的完整性和安全性。
本文将探讨操作系统文件系统的设计原理和实现方式。
一、文件系统的概述文件系统是计算机操作系统中的一个重要组成部分,它负责管理和存储计算机系统中的文件和目录。
文件系统的设计目标通常包括以下几个方面:1. 数据的组织和管理:文件系统需要将文件和目录组织成一个层次结构,并提供对文件和目录的操作和管理。
2. 数据存储和分配:文件系统需要将文件存储在外部存储介质中,并合理分配存储空间,以提高存储利用率。
3. 数据访问和保护:文件系统需要提供高效的数据读写接口,并确保文件的完整性和安全性。
4. 文件系统的可扩展性和性能:文件系统应该具备良好的可扩展性,能够适应不同规模和需求的系统,并提供高速的数据访问性能。
二、文件系统的设计原理1. 文件系统的层次结构:文件系统通常采用层次结构的组织方式,将文件和目录组织成一棵树状结构,便于对文件和目录的操作和管理。
2. 文件的元数据管理:文件系统需要维护每个文件的元数据,包括文件名、文件大小、文件类型、创建时间、修改时间等,以方便文件的访问和管理。
3. 存储空间的分配与管理:文件系统需要对存储介质进行分区,并按照一定的算法来进行存储空间的分配和管理,以提高存储利用率。
4. 文件的存储和访问方式:文件系统通常采用块存储的方式来存储和访问文件,将文件划分为固定大小的块,并使用文件分配表或索引信息来管理文件数据的存储和访问。
5. 数据的缓存和缓存策略:文件系统通常会采用缓存机制来提高数据的访问速度,将最常用的数据缓存至内存中,并使用一定策略进行数据的替换和更新。
三、文件系统的实现方式1. FAT文件系统:FAT文件系统是一种简单易用的文件系统,广泛应用于Windows操作系统和移动存储设备中。
操作系统课程设计报告题目: 为Linux系统设计一个简单的二级文件系统指导老师:时间:2021.8.30一课程设计的目的课程设计目的使学生熟悉文件管理系统的设计方法;加深对所学各种文件操作的了解及其操作方法的特点。
通过模拟文件系统的实现,深入理解操作系统中文件系统的理论知识, 加深对教材中的重要算法的理解。
同时通过编程实现这些算法,更好地掌握操作系统的原理及实现方法,提高综合运用各专业课知识的能力。
二课程设计的要求1.可以实现下列几条命令:login用户登录dir 列目录create创建文件delete 删除文件open 打开文件close 关闭文件read 读文件write 写文件2.列目录时要列出文件名,物理地址,保护码和文件长度3.源文件可以进行读写保护三算法设计本次二级文件系统主要分为五大模块,分别是用户登录模块、新建目录模块、新建文件模块、删除文件模块和读取文件模块。
用户登录成功后才可以进行其他模块的操作。
1 用户登录模块用户登录模块要求用户输入用户,当输入正确后才能进行其他模块操作,否则提示用户名不存在并询问用户是否用此名进行注册。
若用户名未满,则提示注册成功,否则提示用现有注册用户,进行登录,并返回到登录界面。
用户登录模块流程图如图1所示。
图1 用户登录模块流程图2新建文件模块新建文件模块是在用户出入create 指令后进行的,进入后会要求用户输入文件名,并判断文件名是否存在,若没有则在要求用户输入文件读写权限,否则重新输入新的文件名。
新建文件模块流程图如图2所示。
图2 新建文件流程图3 删除文件模块删除文件模块是根据用户鼠标右击时选择到的节点来确定要删除节点的名字与路径,然后判断该节点是目录还是文件。
若是文件则直接删除文件,若是目录则进入该目录再删除其全部文件。
删除文件模块流程图如图4所示。
图4 删除文件模块流程图4读取文件模块读取文件模块,要求用户要在文件打开的前提下,将磁盘中的内容读取到内存中。
简单文件系统的设计及实现一、实验目的:1、用高级语言编写和调试一个简单的文件系统,模拟文件管理的工作过程。
从而对各种文件操作命令的实质内容和执行过程有比较深入的了解2、要求设计一个 n个用户的文件系统,每次用户可保存 m 个文件,用户在一次运行中只能打开一个文件,对文件必须设置保护措施,且至少有 Create 、 delete 、open 、 close 、 read 、 write 等命令。
二、实验内容:1、设计一个 10个用户的文件系统,每次用户可保存 10个文件,一次运行用户可以打开 5个文件。
2、程序采用二级文件目录(即设置主目录 [MFD]和用户文件目录(UED 。
另外,为打开文件设置了运行文件目录(AFD 。
3、为了便于实现,对文件的读写作了简化,在执行读写命令时,只需改读写指针,并不进行实际的读写操作4、算法与框图✓因系统小,文件目录的检索使用了简单的线性搜索。
✓文件保护简单使用了三位保护码:允许读写执行、对应位为 1,对应位为 0, 则表示不允许读写、执行。
✓程序中使用的主要设计结构如下:主文件目录和用户文件目录( MFD、 UFD ; 打开文件目录( AFD(即运行文件目录文件系统算法的流程图如下三、工具 /准备工作:在开始本实验之前,请回顾教科书的相关内容。
并做以下准备: 1 一台运行Windows 2000 Professional或 Windows 2000 Server的操作系统的计算机。
2 计算机中需安装 Visual C++ 6.0专业版或企业版四、实验要求:(1 按照学校关于实验报告格式的要求, 编写实验报告 (含流程图 ;(2实验时按两人一组进行分组,将本组认为效果较好的程序提交检查。
操作系统课程设计-文件系统一、引言文件系统是操作系统中的重要组成部分,负责对计算机中的文件进行管理和组织。
在操作系统课程设计中,文件系统的设计和实现是一个重要的任务。
本文将介绍文件系统的设计原则、功能和实现过程。
二、设计原则1. 可靠性文件系统需要确保数据的可靠性,能够有效地进行错误检测和纠正。
它应该能够处理文件的损坏、删除或丢失等情况,并能够进行数据恢复。
2. 效率文件系统需要具备高效的存取和查找功能,能够在较短的时间内完成对文件的操作。
它应该对文件进行良好的组织和管理,以提高文件的读写速度。
3. 安全性文件系统要能够保护文件的机密性和完整性,确保只有授权用户才能访问文件,并防止数据被恶意篡改或破坏。
4. 可扩展性文件系统应该能够适应不同容量和规模的存储设备,并能够随着存储需求的增长而进行扩展。
三、功能1. 存储管理文件系统需要对存储设备进行管理,包括磁盘空间的分配、回收和整理等操作,确保文件能够高效地存储和读取。
2. 目录管理文件系统需要提供目录管理功能,能够对文件进行组织和分类。
用户可以根据目录结构查找和管理文件,方便文件的查找和访问。
3. 文件操作文件系统需要支持各种文件操作,包括创建、删除、打开、关闭、读取和写入等操作。
它应该提供一组接口供用户和应用程序使用。
4. 错误处理文件系统需要对各种错误情况进行处理,包括磁盘故障、读写错误和用户操作错误等。
它应该能够识别和纠正错误,并提供相应的错误提示和恢复机制。
四、实现过程1. 文件分配文件系统需要确定如何将磁盘空间分配给文件,以实现高效的存储和检索。
常见的文件分配方式包括连续分配、链式分配和索引分配等。
2. 目录结构文件系统需要设计合适的目录结构,以方便用户查找和管理文件。
常见的目录结构包括树状目录结构、索引节点和哈希表等。
3. 文件读写文件系统需要实现高效的文件读写功能,包括将文件从磁盘读入内存和将文件从内存写入磁盘。
它应该提供缓存机制来加速读写操作。
目录第一章设计内容 (1)1.1设计目的 (1)1.2设计要求 (1)1.3程序设计思想 (1)第二章数据结构、算法和算法流程图 (2)2.1数据结构 (2)2.2程序功能图 (2)2.3程序流程图 (3)第三章程序运行结果及分析 (6)3.1程序运行结果 (6)3.2程序分析 (7)第四章心得体会 (8)参考文献 (9)附录程序清单 (10)第一章设计内容1.1 设计目的通过设计一个小型文件系统,进一步掌握文件管理的方法和技术,使学生初步具有研究、设计、编制和调试操作系统模块的能力。
1.2 设计要求(1) 问题描述在任一OS下,建立一个大文件,把它假想成一张盘,在其中实现一个简单的小型文件系统。
(2) 基本要求该文件系统没有子目录机制,文件连续分配,不考虑换“盘”和分区。
做一个简单的操作界面,提供五条简单的命令:dir、mkfile、type、copy、delfile,分别用于显示文件目录、建立文件、显示文件内容、复制和删除一个文件。
1.3 程序设计思想阅读操作系统方面的书籍,了解操作系统的文件系统原理。
结合分析课程设计要求,确定实体以及它们之间的关系。
实体关系有三张表(磁盘空间分配表、文件表、打开文件表)、一个模拟磁盘的数组、命令服务和用户构成。
用户负责输入命令。
命令服务实现命令的解释、命令检查、命令帮助以及调用相关模块执行相应的命令功能。
建立一个系统文件(模拟盘),并对此进行盘块的划分,第一个盘块存放文件目录,第二盘块存放盘块位示图,自第三个盘块开始存放各具体文件的内容,文件目录存放文件的名字,文件的扩展名,开始盘块号,所占用的盘块数目,文件的大小;盘块位示图用来标记盘块是否被占用。
构造这些实体的关系图,数据流图、程序流程图来进行具体的设计。
第二章数据结构、算法和算法流程图2.1 数据结构数据结构说明:本程序所运用的主要有两个数据结构,分别如下:文件目录结构:struct filename { //文件目录项结构体char name[9]; //文件名char ext[4]; //扩展名int i; //文件所占用磁盘块的第一个磁盘块号int Amount; //文件所占用磁盘块的块数long int size; //文件大小};盘块结构:struct empty { //盘块结构体int map[100]; //盘块位示图int filenum; //文件数量};2.2 程序功能图图2.1文件系统提供的文件操作有建立文件(mkfile)、复制文件(copy)、显示文件所有内容(type)、删除文件(delfile)。
模拟一个简单二级文件管理系统设计目的:通过具体的文件存储空间的管理、文件的物理结构、目录结构和文件操作的实现,加深对文件系统内部功能和实现过程的理解。
设计内容:模拟一个简单二级文件管理系统一、实验内容描述1 实验目标本实验的目的是通过一个简单多用户文件系统的设计,加深理解文件系统的内部功能及内部实现.2 实验要求为DOS系统设计一个简单的二级文件系统.要求做到以下几点:①可以实现下列命令:login 用户登录dir 列文件目录create 创建文件delete 删除文件open 打开文件close 关闭文件read 读文件write 写文件②列目录时要列出文件名、物理地址、保护码和文件长度.③源文件可以进行读写保护.二、程序主要内容1设计思路程序中要求每个用户在登陆后才可对其拥有的文件进行操作,用户对于其他用户的文件无操作权.文件操作包括浏览、创建、删除、打开、关闭、阅读、写入、修改模式.其他操作包括新建用户、帮助、用户登入、用户登出、退出系统.在程序文件夹下有个名为“file”的系统根目录,此目录下包括:一个名为“mfd”的文件,记录所有注册过的帐号及密码;用户文件,以用户名作为文件名,内容为其拥有的文件名及属性;一个名为“keiji”的文件夹.“keiji”文件夹中包括:“file.p”指针文件,记录所有已用的物理地址;一些以物理地址为名的文件,内容为文件内容.2 数据结构file结构体系统文件数据结构:fpaddrint,文件的物理地址、flengthint,文件长度、fmodeint,文件模式0.只读;1.可写;2.可读写;3.保护、fname[]char,文件名;filemode结构体文件状态数据结构:isopenint,文件当前状态,0.关闭;1.打开、modeint,文件模式0.只读;1.可写;2.可读写;3.初始化;user结构体用户信息数据结构:uname[]char,用户名、upassword[]char,用户密码;userfile结构体用户文件数据结构:uname[]char,用户名、ufile[]file,用户拥有的文件数组.代码:#include <stdio.h>#include <stdlib.h>#include <conio.h>#include <time.h>#include <string.h>#define MaxUser 100 //定义最大MDF主目录文件#define MaxDisk 512*1024 //模拟最大磁盘空间#define commandAmount 12 //对文件操作的指令数//存储空间管理有关结构体和变量char disk[MaxDisk]; //模拟512K的磁盘存储空间typedef struct distTable //磁盘块结构体{int maxlength;int start;int useFlag;distTable *next;}diskNode;diskNode *diskHead;struct fileTable //文件块结构体{char fileName[10];int strat; //文件在磁盘存储空间的起始地址int length; //文件内容长度int maxlength; //文件的最大长度char fileKind[3]; //文件的属性——读写方式struct tm *timeinfo;bool openFlag; //判断是否有进程打开了该文件//fileTable *next;};//两级目录结构体typedef struct user_file_directory //用户文件目录文件UFD {//char fileName[10];fileTable *file;user_file_directory *next;}UFD;//UFD *headFile;typedef struct master_file_directory //主文件目录MFD{char userName[10];char password[10];UFD *user;}MFD;MFD userTable[MaxUser];int used=0; //定义MFD目录中用已有的用户数//文件管理void fileCreate(char fileName[],int length,char fileKind[]); //创建文件void fileWrite(char fileName[]); //写文件void fileCat(char fileName[]); //读文件void fileRen(char fileName[],char rename[]); //重命名文件void fileFine(char fileName[]); //查询文件void fileDir(char UserName[]); //显示某一用户的所有文件void fileClose(char fileName[]); //关闭已打开的文件void fileDel(char fileName[]); //删除文件void chmod(char fileName[],char kind[]); //修改文件的读写方式int requestDist(int &startPostion,int maxLength); //磁盘分配查询void initDisk(); //初始化磁盘void freeDisk(int startPostion); //磁盘空间释放void diskShow(); //显示磁盘使用情况//用户管理void userCreate();int login();int userID=-1; //用户登录的ID号,值为-1时表示没有用户登录int main(){char order[commandAmount][10];strcpy(order[0],"create");strcpy(order[1],"rm");strcpy(order[2],"cat");strcpy(order[3],"write");strcpy(order[4],"fine");strcpy(order[5],"chmod");strcpy(order[6],"ren");strcpy(order[7],"dir");strcpy(order[8],"close");strcpy(order[9],"return");strcpy(order[10],"exit");strcpy(order[11],"df");char command[50],command_str1[10],command_str2[10],command_str3[5],command_str4[3];int i,k,j;int length;initDisk(); //初始化磁盘for(i=0;i<MaxUser;i++) //初始化用户UFD目录文件的头指针{userTable[i].user=(UFD *)malloc(sizeof(UFD));userTable[i].user->next=NULL;}while(1){printf("********************************************\n");printf(" 1、Creat user\n");printf(" 2、login\n");printf("********************************************\n");printf("Please chooce the function key:>");int choice;scanf("%d",&choice);if(choice==1) userCreate();else if(choice==2) userID=login();else printf("您的输入有误,请重新选择\n");while(userID!=-1){fflush(stdin);printf("———————————————————————————————————————\n ");printf(" create-创建格式:create a1 1000 rw,将创建名为a1,长度为1000字节可读可写的文件\n");printf(" rm-删除格式:rm a1,将删除名为a1的文件\n");printf(" cat-查看文件内容格式:cat a1,显示a1的内容\n");printf(" write-写入格式:write a1\n");printf(" fine-查询格式:fine a1 ,将显示文件a1的属性\n");printf(" chmod-修改格式:chmod a1 r,将文件a1的权限改为只读方式\n");printf(" ren-重命名格式:ren a1 b1 ,将a1改名为b1\n");printf(" dir-显示文件格式:dir aaa,将显示aaa用户的所有文件\n");printf(" df-显示磁盘空间使用情况格式:df\n");printf(" close-关闭文件格式:close a1,将关闭文件a1\n");printf(" return-退出用户,返回登录界面\n");printf(" exit-退出程序\n");printf("————————————————————————————————————————\n");printf("please imput your command:>");gets(command);int select;for(i=0;command[i]!=' '&&command[i]!='\0';i++) //command_str1字符串存储命令的操作类型command_str1[i]=command[i];k=i;command_str1[k]='\0';for(i=0;i<commandAmount;i++){if(!strcmp(command_str1,order[i])){select=i;break;}}if(i==commandAmount){printf("您输入的命令有误,请重新输入\n");continue;}for(i=k+1,k=0;command[i]!=' '&&command[i]!='\0';i++,k++) //commmand_str2字符串存储文件名或用户名command_str2[k]=command[i];command_str2[k]='\0';k=i;switch(select){case 0:for(i=k+1,k=0;command[i]!=' ';i++,k++)command_str3[k]=command[i];command_str3[k]='\0';k=i;j=1;length=0; //初始化文件长度for(i=strlen(command_str3)-1;i>=0;i--) //把字符串转换为十进制{length+=(command_str3[i]-48)*j;j*=10;}for(i=k+1,k=0;command[i]!=' '&&command[i]!='\0';i++,k++)command_str4[k]=command[i];command_str4[k]='\0';fileCreate(command_str2,length,command_str4);break;case 1:fileDel(command_str2);break;case 2:fileCat(command_str2);break;case 3:fileWrite(command_str2);break;case 4:fileFine(command_str2);break;case 5:for(i=k+1,k=0;command[i]!=' '&&command[i]!='\0';i++,k++)command_str3[k]=command[i];command_str3[k]='\0';chmod(command_str2,command_str3);break;case 6:for(i=k+1,k=0;command[i]!='\0';i++,k++)command_str3[k]=command[i];command_str3[k]='\0';fileRen(command_str2,command_str3);break;case 7:fileDir(command_str2);break;case 8:fileClose(command_str2);break;case 9:UFD *p;for(p=userTable[userID].user->next;p!=NULL;p=p->next) //退出用户之前关闭所有打的文件if(p->file->openFlag)p->file->openFlag=false;system("cls");userID=-1;break;case 10:exit(0);break;case 11:diskShow();break;}}}return 0;}void userCreate(){char c;char userName[10];int i;if(used<MaxUser){printf("请输入用户名:");for(i=0;c=getch();i++){if(c==13) break;elseuserName[i]=c;printf("%c",c);}userName[i]='\0';for(i=0;i<used;i++){if(!strcmp(userTable[i].userName,userName)){printf("\n");printf("该用户名已存在,创建用户失败\n");system("pause");return;}}strcpy(userTable[used].userName,userName);printf("\n");printf("请输入密码:");for(i=0;c=getch();i++){if(c==13) break;elseuserTable[used].password[i]=c;printf("*");}userTable[userID].password[i]='\0';printf("\n");printf("创建用户成功\n");used++;system("pause");}else{printf("创建用户失败,用户已达到上限\n");system("pause");}fflush(stdin);}int login(){char name[10],psw[10];char c;int i,times;printf("请输入用户名:");for(i=0;c=getch();i++){if(c==13) break;elsename[i]=c;printf("%c",c);}name[i]='\0';for(i=0;i<used;i++){if(!strcmp(userTable[i].userName,name))break;}if(i==used){printf("\n您输入的用户名不存在\n");system("pause");return -1;}for(times=0;times<3;times++){memset(psw,'\0',sizeof(psw));printf("\n请输入密码:");for(i=0;c=getch();i++){if(c==13) break;elsepsw[i]=c;printf("*");}printf("\n");for(i=0;i<used;i++){if(!strcmp(psw,userTable[i].password)){printf("用户登录成功\n");system("pause");break;}}if(i==used){printf("您输入的密码错误,您还有%d次输入机会\n",2-times);if(times==2) exit(0);}else break;}fflush(stdin);return i;}void initDisk(){diskHead=(diskNode *)malloc(sizeof(diskNode));diskHead->maxlength=MaxDisk;diskHead->useFlag=0;diskHead->start=0;diskHead->next=NULL;}int requestDist(int &startPostion,int maxLength){int flag=0; //标记是否分配成功diskNode *p,*q,*temp;p=diskHead;while(p){if(p->useFlag==0&&p->maxlength>maxLength){startPostion=p->start;q=(diskNode *)malloc(sizeof(diskNode));q->start=p->start;q->maxlength=maxLength;q->useFlag=1;q->next=NULL;diskHead->start=p->start+maxLength;diskHead->maxlength=p->maxlength-maxLength;flag=1;temp=p;if(diskHead->next==NULL) diskHead->next=q;else{while(temp->next) temp=temp->next;temp->next=q;}break;}p=p->next;}return flag;}void fileCreate(char fileName[],int length,char fileKind[]){//int i,j;time_t rawtime;int startPos;UFD *fileNode,*p;for(p=userTable[userID].user->next;p!=NULL;p=p->next){if(!strcmp(p->file->fileName,fileName)){printf("文件重名,创建文件失败\n");system("pause");return;}}if(requestDist(startPos,length)){fileNode=(UFD *)malloc(sizeof(UFD));fileNode->file=(fileTable *)malloc(sizeof(fileTable)); //这一步必不可少,因为fileNode里面的指针也需要申请地址,否则fileNode->file指向会出错strcpy(fileNode->file->fileName,fileName);strcpy(fileNode->file->fileKind,fileKind);fileNode->file->maxlength=length;fileNode->file->strat=startPos;fileNode->file->openFlag=false;time(&rawtime);fileNode->file->timeinfo=localtime(&rawtime);fileNode->next=NULL;if(userTable[userID].user->next==NULL)userTable[userID].user->next=fileNode;else{p=userTable[userID].user->next;while(p->next) p=p->next;p->next=fileNode;}printf("创建文件成功\n");system("pause");}else{printf("磁盘空间已满或所创建文件超出磁盘空闲容量,磁盘空间分配失败\n");system("pause");}}void freeDisk(int startPostion){diskNode *p;for(p=diskHead;p!=NULL;p=p->next){if(p->start==startPostion)break;}p->useFlag=false;}void fileDel(char fileName[]){UFD *p,*q,*temp;q=userTable[userID].user;p=q->next;while(p){if(!strcmp(p->file->fileName,fileName)) break;else{p=p->next;q=q->next;}}if(p){if(p->file->openFlag!=true) //先判断是否有进程打开该文件{temp=p;q->next=p->next;freeDisk(temp->file->strat); //磁盘空间回收free(temp);printf("文件删除成功\n");system("pause");}else{printf("该文件已被进程打开,删除失败\n");system("pause");}}else{printf("没有找到该文件,请检查输入的文件名是否正确\n");system("pause");}}void fileCat(char fileName[]){int startPos,length;int k=0;UFD *p,*q;q=userTable[userID].user;for(p=q->next;p!=NULL;p=p->next){if(!strcmp(p->file->fileName,fileName))break;}if(p){startPos=p->file->strat;length=p->file->length;p->file->openFlag=true; //文件打开标记printf("*****************************************************\n");for(int i=startPos;k<length;i++,k++){if(i%50==0) printf("\n"); //一行大于50个字符换行printf("%c",disk[i]);}printf("\n\n*****************************************************\n");printf("%s已被read进程打开,请用close命令将其关闭\n",p->file->fileName);system("pause");}else{printf("没有找到该文件,请检查输入的文件名是否正确\n");system("pause");}}void fileWrite(char fileName[]){UFD *p,*q;q=userTable[userID].user;int i,k,startPos;for(p=q->next;p!=NULL;p=p->next){if(!strcmp(p->file->fileName,fileName))break;}if(p){if(!strcmp(p->file->fileKind,"r")) //判断文件类型{printf("该文件是只读文件,写入失败\n");system("pause");return;}char str[500];printf("please input content:\n");gets(str);startPos=p->file->strat;p->file->openFlag=true; //文件打开标记p->file->length=strlen(str);if(p->file->length>p->file->maxlength){printf("写入字符串长度大于该文件的总长度,写入失败\n");system("pause");return;}for(i=startPos,k=0;k<(int)strlen(str);i++,k++)disk[i]=str[k];printf("文件写入成功,请用close命令将该文件关闭\n");system("pause");}else{printf("没有找到该文件,请检查输入的文件名是否正确\n");system("pause");}}void fileFine(char fileName[]){UFD *p,*q;q=userTable[userID].user;for(p=q->next;p!=NULL;p=p->next){if(!strcmp(p->file->fileName,fileName))break;}if(p){printf("********************************************\n");printf("文件名:%s\n",p->file->fileName);printf("文件长度:%d\n",p->file->maxlength);printf("文件在存储空间的起始地址:%d\n",p->file->strat);printf("文件类型:%s\n",p->file->fileKind);printf("创建时间:%s\n",asctime(p->file->timeinfo));printf("********************************************\n");system("pause");}else{printf("没有找到该文件,请检查输入的文件名是否正确\n");system("pause");}}void chmod(char fileName[],char kind[]){UFD *p,*q;q=userTable[userID].user;for(p=q->next;p!=NULL;p=p->next){if(!strcmp(p->file->fileName,fileName))break;}if(p){strcpy(p->file->fileKind,kind);printf("修改文件类型成功\n");system("pause");}else{printf("没有找到该文件,请检查输入的文件名是否正确\n");system("pause");}}void fileRen(char fileName[],char name[]){UFD *p,*q;q=userTable[userID].user;for(p=q->next;p!=NULL;p=p->next){if(!strcmp(p->file->fileName,fileName))break;}if(p){while(q->next){if(!strcmp(q->next->file->fileName,name)){printf("您输入的文件名已存在,重命名失败\n");system("pause");return;}q=q->next;}strcpy(p->file->fileName,name);printf("重命名成功\n");system("pause");}else{printf("没有找到该文件,请检查输入的文件名是否正确\n");system("pause");}}void fileDir(char userName[]){UFD *p;int i,k;for(i=0;i<MaxUser;i++){if(!strcmp(userTable[i].userName,userName)){k=i;break;}}if(i==MaxUser){printf("没有找到该用户,请检查输入用户名是否正确\n");system("pause");return;}else{p=userTable[k].user->next;printf("******************************************************************************* *\n");printf("文件名文件长度文件在磁盘的起始地址文件类型创建时间\n");for(;p!=NULL;p=p->next)printf("%s %d %d %s %s",p->file->fileName,p->file->maxlength,p->file->strat,p->file->fileKind,asctime(p->file->timeinfo));printf("******************************************************************************* *\n");system("pause");}}void diskShow(){diskNode *p;int i=0,unusedDisk=0;printf("***************************************************************************\n");printf(" 盘块号起始地址容量(bit) 是否已被使用\n");for(p=diskHead;p!=NULL;p=p->next,i++){if(p->useFlag==false) unusedDisk+=p->maxlength;printf(" %d %d %d %d \n",i,p->start,p->maxlength,p->useFlag);}printf("***************************************************************************\n");printf("磁盘空间总容量:512*1024bit 已使用:%dbit 末使用:%dbit\n\n",MaxDisk-unusedDisk,unusedDisk);system("pause");}void fileClose(char fileName[]){UFD *p,*q;q=userTable[userID].user;for(p=q->next;p!=NULL;p=p->next){if(!strcmp(p->file->fileName,fileName))break;}if(p){p->file->openFlag=false;printf("%s文件已关闭\n",p->file->fileName);system("pause");}else{printf("没有找到该文件,请检查输入的文件名是否正确\n");system("pause");}}运行结果视图:(略)。
课程设计报告( 20 --20 年度第学期)课程名称:操作系统实验课设题目:文件系统的实现院系:控制与计算机工程学院班级:姓名:指导教师:设计周数:一周成绩:20 年月日设计报告内容一、需求分析用C或C++编写和调试一个文件系统,功能使用命令行的方式实现。
模拟文件管理的工作过程。
加深理解文件系统的内部功能和内部实现。
用内存模拟磁盘用结构体数组描述个不同的磁盘区域。
磁盘的存取单元是磁盘块,一个盘块的大小是64字节。
每个目录项16个字节,目录项下只允许建立4个子目录或者文件。
i-node位图1块64个字节,共512位,可以描述512个i-node的使用情况。
i-node的长度是16字节。
文件超过两个盘块会用到一级索引。
每个以及索引盘块(64字节)可以包含16个盘块号。
文件包含目录文件和文本文件。
实现Format,Mkfile,Mkdir,Cd,Delfile,Deldir,Dir,Copy,Open,Viewinodebitmap,V iewblockbitmap等功能。
二、整体功能及设计(功能划分及流程图)1、数据结构:struct DirectoryEntry{ //目录项char name[8]; //文件或目录名int dirid; //目录标志(0为文件,1为目录)int inodenumber; //i-node编号};struct DirectoryEntryInBlock{DirectoryEntry de[4]; //每个目录项大小为16字节,64字节空间最多可以存储4个目录项int num; //磁盘块存储的目录项数目};struct indexaddressstruct{int indexaddress[16]; //每个索引块大小为4字节,64字节空间最多可以存储16个索引块号int num; //索引块存储的索引数目};union Block{ //单个盘块64个字节大小可以存储文件内容或者存储目录项或者存储索引块号char space[64]; //空间大小为64个字节用于存储文件内容DirectoryEntryInBlock deib;indexaddressstruct ias;};struct inodeStruct{ //i-node结构int blockamount; //盘块数int directblockaddress1,directblockaddress2; //直接盘块地址*2int stairindexaddress; //一级索引地址};struct DiskBlock{ //磁盘布局DirectoryEntry rootdirectory[4]; //根目录,最多4个目录项char inodebitmap[512]; //512个i-node状态char blockbitmap[1024]; //1024个磁盘块状态inodeStruct inode[512]; //512个i-node存储区Block datablock[1024]; //数据块存储区};static DiskBlock db; //全局磁盘变量int rootdirectoryamount; //用于记录根目录的使用数目,最大为4 int inodeamount; //用于记录i-node的使用数目,最大为512int datablockamount; //用于记录数据块的使用数目,最大为1024int spaceamount; //用于记录数据块中64位字节的使用数目,最大为64 DirectoryEntry filelist[500]; //用于记录文件方便遍历检索DirectoryEntry directorylist[500]; //用于记录目录方便int fileamount; //用于记录文件数目int directoryamount; //用于记录目录的数目char localposition[8]; //用于记录当前位置2、文件系统相关图(1)文件系统简单结构图如图1所示。
如何编写一个简单的操作系统文件系统操作系统文件系统是操作系统管理存储设备上文件和目录的系统。
它的设计和实现对操作系统的性能和功能有着重要的影响。
一个好的文件系统需要具备高效的存储管理、可靠的数据存储和恢复机制、良好的用户接口等特点。
下面通过简单的文件系统设计来介绍文件系统的基本原理和实现步骤。
一、文件系统的基本要求1.存储管理:文件系统需要能够有效地管理存储设备上的存储空间,实现文件的分配和释放。
2.数据存储与恢复:文件系统需要具备数据持久化的能力,能够保证文件在存储设备上安全存储,并能够在系统崩溃时自动恢复数据。
3.文件操作接口:文件系统需要提供用户友好的文件操作接口,如读取、写入、创建、删除、重命名等操作。
二、文件系统设计1.文件控制块(FCB):文件系统中的每个文件都有对应的文件控制块,用来存储文件的基本信息,如文件名、大小、创建时间、修改时间、访问权限等。
2.目录结构:文件系统需要维护一个目录结构,用来记录文件和目录的层次关系。
可以采用树形结构来组织目录,每个目录节点包含文件或子目录的信息。
3.空闲块管理:文件系统需要通过空闲块管理来实现文件存储空间的分配和释放。
可以采用位图或空闲块链表的方式进行管理。
4.存储分配策略:文件系统需要设计合适的存储分配策略,如连续分配、链式分配、索引分配等。
不同的分配策略对文件系统的性能和可靠性有着重要影响。
5.数据恢复机制:文件系统需要设计合适的数据恢复机制来保证文件在系统崩溃时能够正确地恢复数据。
可以采用日志、备份、快照等方式来实现数据恢复。
6.用户接口:文件系统需要提供良好的用户接口,使用户能够方便地进行文件操作。
可以设计命令行或图形界面来实现用户与文件系统的交互。
三、文件系统实现步骤1.设计文件控制块结构:根据文件系统的需求,设计合适的文件控制块结构,包括文件名、文件大小、创建时间、修改时间、访问权限等字段。
2.设计目录结构:根据文件系统的需求,设计合适的目录结构,包括目录名称、父目录、子目录和文件的信息等字段。
《操作系统》课程设计题目:设计一个简单二级文件系统专业:计算机科学与技术年级:文专计081—1姓名:张庆龙学号:0126指导教师:翟一鸣时间:2010年7 月15日一、设计内容1、可以实现下列几条命令。
Format 格式化Dir 列文件目录Create 创建文件Delete 删除文件Deldir 删除目录Open 打开文件Close 关闭文件Search 查询文件Copy 拷贝文件Cut 剪切文件二、开发环境Windows操作系统Microsoft Visual C++三、分析设计(一)实验原理通过程序模拟Linux文件系统,用一个二进制文件(FileSystem.disk)来模拟磁盘.设计一个多用户的二级文件系经统、实现一般的创建文件、目录,删除文件、目录,切换目录,打开、关闭文件、读写文件等操作。
文件系统,包含格式化,显示文件(目录),创建文件等几个简单命令的实现,而且能完成超级块的读写,节点的读写等过程. 本文件系统采用两级目录,其中第一级对应于用户账号,第二级对应于用户账号下的文件。
另外,为了简单本文件系统未考虑文件共享、文件系统安全以及管道文件与设备文件等特殊内容。
1.程序执行流程图:2.数据块的分配和回收(二)程序结构设计FileSystem类负责管理磁盘空间和磁盘内存I节点,负责对磁盘空间和磁盘数据进行优化管理。
并提代接口言方法供用户或程序调用。
(三)数据结构int physic[100]; //文件地址缓冲区int style=1; //文件的类型char cur_dir[10]="root"; //当前目录int search_i=0;struct command{char com[10];}cmd[20];struct block{int n; //空闲的盘快的个数int free[50]; //存放空闲盘快的地址int a; //模拟盘快是否被占用}memory[20449];struct block_super{int n; //空闲的盘快的个数int free[50]; //存放进入栈中的空闲块int stack[50]; //存放下一组空闲盘快的地址}super_block;struct node //i结点信息{int file_style; //i结点文件类型int file_length; //i结点文件长度int file_address[100]; //i结点文件的物理地址 char file_message[100];} i_node[640];struct dir //目录项信息{char file_name[10]; //文件名int i_num; //文件的结点号char dir_name[10]; //文件所在的目录} root[640];四. 运行示例及结果分析菜单删除目录文件查询拷贝剪切五、程序实现详细程序请参见源文件, 在此只列举3点1、剪切文件程序片段:void cut(char *tmp,char *newname){int i; //,jchar t[20];_strtime(t);for(i=0;i<640;i++)if(strcmp(newname,root[i].file_name)==0){break;}if(i==640){printf("目录不存在,不能剪切!\n");return;}for(i=0;i<640;i++){if(strcmp(tmp,root[i].file_name)==0){strcpy(root[i].dir_name,newname);strcpy(i_node[root[i].i_num].change_t,t);//printf("剪切成功!\n");//return;}}if(i==640)printf("文件不存在,执行失败!\n");}2.无文件查询程序片段:void search(char* filename){int sign=0;for(search_i=0;search_i<640;search_i++){if(strcmp(root[search_i].file_name,filename)==0) //查询文件中所在目录信息和当前目录信息相同的数据{sign=1;int k=root[search_i].i_num;printf("%s\t",root[search_i].file_name); //文件名printf(" %d\t",i_node[k].file_style); //文件的类型printf(" %d\t\t",i_node[k].file_length); //文件的长度printf("%s\n",root[search_i].dir_name); //文件所在的目录}}if (sign==0){printf("%s\n","未找到该文件!");}}六、心得与体会这次设计中遇到最难的问题就是拷贝功能的实现,由于之前没有接触过拷贝的原理,所以通过和同伴的讨论和试验,终于突发奇想的运用改变文件路径的源代码和创建文件相结合,终于实现了拷贝功能,能够将一个文件从一个目录拷贝到另一目录(即先移动过去然后再在原位置创建一个原文件),可是却无法拷贝到root根目录,为了解决这个问题,又在创建文件的程序里添加了一个判断是否为根目录的语句,可是后来又发现了真个系统存在重命名的问题。
杭州电子科技大学操作系统课程设计课程设计题目:简单文件系统的实现姓名:庄严班级:09056011学号:09056012学院:计算机学院专业:计算机科学与技术(2+2)负责老师:胡志凌完成日期:2012-5-28简单文件系统的实现一,课程设计的目的1,通过具体的文件爱你存储空间的管理、文件的物理结构、目录结构和文件操作的实现,加深对文件系统内部数据结、功能及实现过程的理解二,设计要求1,在内存中开辟一个虚拟磁盘空间作为文件存储分区,在其上实现一个简单的基于多级目录的但用户单任务系统的文件系统。
在退出文件系统的使用时,应将虚拟文件系统一个Windows文件的方式保存到磁盘中,以便下次再将它恢复到内存的虚拟磁盘空间中2,文件存储空间的分配可采用显示链接分配或其它方法3,空闲磁盘空间的管理可选择位示图或其它方法4,文件目录结构采用多级目录结构5,需要提供一以下操作命令i.Formatii.Mkdiriii.Rmdiriv.Lsv.Cdvi.Createvii.Openviii.Closeix.Writex.Readxi.Rmxii.Exit三,程序设计思想以及总流程图1,程序设计思想i.首先,在文件系统启动时,申请一块较大的内存,用来当作文件系统的磁盘空间ii.然后,对其进行格式化,虚拟磁盘的空间布局是仿照FA T16文件系统,结构如下:1块2块2块995块引导块 FA T1 FA T2 数据区格式化时,主要包括引导块,FA T1,FA T2,的一些初始化工作例如设置文件魔数,文件系统的信息,FA T1,FA T2的信息等等iii.根据用户输入的命令,调用对应的函数.2,程序流程图四,系统各个功能的实现思想1,创建目录a)调用do_read读入当前目录文件到内存,检查新建文件目录是否重名b)分配一个空闲的打开文件表项c)分配一个空闲的盘块d)在当前目录中问新建目录寻找一个空闲的目录项e)设置FCB,文件的属性信息f)创建特殊的两个目录项‘.’,‘..’g)返回2,Cd命令a)Open指定的目录名,调用read读入该父目录到内存b)检查新的当前目录名是否存在c)关闭原当前目录d)设置当前目录为该目录3,Rmdir命令a)Read读入当前目录文件内容到内存,检查要删除的文件目录是否存在b)检查该目录是否为空c)检查是否已经打开,打开用close则关闭d)回收给目录文件的磁盘块e)修改该目录文件的目录项f)修改用户打开表项的长度信息g)返回4,Ls命令a)Read当前目录到内存b)读出目录文件的信息,显示到屏幕上c)返回5,Create命令a)分配一个空闲的打开文件表项b)检查新文件的父目录是否打开c)Read该父目录的文件到内存,并检测新建的文件名是否重名d)检查是否有空闲盘块e)寻找空闲的目录项f)准备好新文件的F CBg)调用close关闭打开的父目录文件h)返回6,Rm命令a)检查要删除的文件的父目录是否已打开b)Read父目录到内存c)检查文件是否打开d)回收磁盘快e)清空该文件的目录项f)修改用户打开文件表项中的长度信息g)返回7,Open命令a)检查该文件名是否存在b)Read该父目录到内存c)检查用户打开的文件表中是否有空闲表项d)为该文件填写空白用户打开文件表项内容e)返回8,Closea)检查fd的有效性b)检查用户打开文件表表项的fcbstate字段c)回收该文件占据的用户打开文件表表项d)返回9,Write命令a)检查fd的有效性b)提示用户输入写方式c)提示用户输入内容d)调用do_write()将键入的内容写入到文件中e)返回写入的字节数五,系统的详细过程#include<stdio.h>#include<malloc.h>#include<time.h>#include<stdlib.h>#include<str ing.h>#define BLOCKSIZE 1024#define SIZE 1024000#define END 65535#define FREE 0#define ROOT_BLOC KNUM 2#define MAX_OPEN_FILE 10#define MAX_TXT_SIZE 10000typedef struct FCB{char filename[8]; /*8B文件名*/char exname[3]; /*3B扩展名*/unsigned char attr ibute; /*文件属性字段*/char retainbyte[10] ; /*10B保留字*/unsigned short time; /*文件创建时间*/unsigned short date; /*文件创建日期*/unsigned short first; /*首块号*/unsigned long length; /*文件大小*/}fcb;/*文件分配表file allocation table*/typedef struct FAT{unsigned short id;}fat;/*属性对照表位7 6 5 4 3 2 1 0属性保留保留存档子目录卷标系统文件隐藏只读*/typedef struct USEROPEN{char filename[8]; /*8B文件名*/char exname[3]; /*3B扩展名*/unsigned char attr ibute; /*文件属性字段*/char retainbyte[10] ; /*10B保留字*/unsigned short time; /*文件创建时间*/unsigned short date; /*文件创建日期*/unsigned short first; /*首块号*/unsigned long length; /*文件大小*/char free; /*表示目录项是否为空0空1分配*/int father; /*父目录的文件描述符*/int dirno; /*相应打开文件的目录项在父目录文件中的盘块号*/int diroff; /*相应打开文件的目录项在父目录文件的dirno盘块中的目录项序号*/ char dir[MAX_OPEN_FILE][80];/*相应打开文件所在的目录*/int count; /*读写指针在文件中的位置*/char fcbstate; /*是否修改了文件的FCB内容,修改置1,否则为0*/char topenfile; /*表示该用户打开的表项是否为空,若值为0,表示为空*/}useropen;typedef struct BLOCK0{unsigned short fbnum;char information[200];unsigned short root;unsigned char *startblock;}block0;/*全局变量定义*/unsigned char *myvhard; /*指向虚拟磁盘的起始地址*/useropen openfilelist[MAX_OPEN_FILE]; /*用户打开文件表数组*/useropen *ptrcurdir; /*指向用户打开文件表中的当前目录所在打开文件表项的位置*/ int curfd;char currentdir[80]; /*记录当前目录的文件名*/unsigned char *startp; /*记录虚拟磁盘上数据区开始位置*/char filename[]="c:\\myfilesys"; /*虚拟空间保存路径*/unsigned char buffer[SIZE];/*函数声明*/void startsys();void my_for mat();void my_cd(char *dirname);void my_mkdir(char *dirname);void my_rmdir(char *dir name);void my_ls();void my_create(char *filename);void my_rm(char *filename);int my_open(char *filename);int my_close(int fd);int my_wr ite(int fd);int do_write(int fd,char *text,int len,char wstyle);unsigned short findFree();int my_read(int fd,int len);int do_read(int fd,int len,char *text);void my_exitsys();/*函数设计*//*文件系统初始化*//*原型声明: void startsys()功能描述:文件系统初始化,初始化所建立的文件系统输入:无输出:无函数功能实现算法描述:1)申请磁盘空间2)打开系统磁盘,若不存在,创建新的系统磁盘,并格式化3)初始化用户打开文件表,将表项0分配给根目录文件使用并填写根目录文件的相关信息4)将ptrcurdir指向该用户打开文件表项5)将当前目录设置为根目录*/void startsys(){FILE *fp;int i;myvhard=(unsigned char *)malloc(SIZE);memset(myvhard,0,SIZE);fp=fopen(filename,"r");if(fp){fread(buffer,SIZE,1,fp);fclose(fp);if(buffer[0]!=0xaa||buffer[1]!=0xaa){printf("myfilesys is not exist,begin to creat the file...\n");my_for mat();}else{for(i=0;i<SIZE;i++)myvhard[i]=buffer[i];}}else{printf("myfilesys is not exist,begin to creat the file...\n");my_for mat();}strcpy(openfilelist[0].filename,"root");strcpy(openfilelist[0].exname,"di");openfilelist[0].attribute=0x2d;openfilelist[0].time=((fcb *)(myvhard+5*BLOCKSIZE))->time;openfilelist[0].date=((fcb *)(myvhard+5*BLOC KSIZE))->date;openfilelist[0].first=((fcb *)(myvhard+5*BLOCKSIZE))->first;openfilelist[0].length=((fcb *)(myvhard+5*BLOCKSIZE))->length; openfilelist[0].free=1;openfilelist[0].dirno=5;openfilelist[0].diroff=0;openfilelist[0].count=0;openfilelist[0].fcbstate=0;openfilelist[0].topenfile=0;openfilelist[0].father=0;memset(currentdir,0,sizeof(currentdir));strcpy(currentdir,"\\root\\");strcpy(openfilelist->dir[0],currentdir);startp=((block0 *)myvhard)->startblock;ptrcurdir=&openfilelist[0];curfd=0;}/*原型声明: void my_for mat()功能描述:对虚拟磁盘进行格式化,布局虚拟磁盘,建立根目录文件输入:无输出:无函数功能实现算法描述:虚拟磁盘空间布局1块2块2块995块引导块FAT1 FAT2 数据区虚拟磁盘一共划分成1000个磁盘块每块1024个字节,磁盘空间布局如上将数据区的第一块(即虚拟磁盘的第6块)分配给根目录文件*/void my_for mat(){FILE *fp;fat *fat1,*fat2;block0 *b0;time_t *now;struct tm *nowtime;unsigned char *p;fcb *root;int i;p=myvhard;b0=(block0 *)p;fat1=(fat *)(p+BLOCKSIZE);fat2=(fat*)(p+3*BLOCKSIZE);/*引导块*/b0->fbnum=0xaaaa; /*文件系统魔数10101010*/b0->root = 5;strcpy(b0->information,"My FileSystem Ver 1.0 \n Blocksize=1KB Whole size=1000KB Blocknum=1000 RootBlocknum=2\n");/*FAT1,FAT2前面五个磁盘块已分配,标记为END*/fat1->id=END;fat2->id=END;fat1++;fat2++;fat1->id=END;fat2->id=END;fat1++;fat2++;fat1->id=END;fat2->id=END;fat1++;fat2++;fat1->id=END;fat2->id=END;fat1++;fat2++;fat1->id=END;fat2->id=END;fat1++;fat2++;fat1->id=6;fat2->id=6;fat1++;fat2++;fat1->id=END;fat2->id=END;fat1++;fat2++;/*将数据区的标记为空闲状态*/for(i=7;i<SIZE/BLOC KSIZE;i++){(*fat1).id=FREE;(*fat2).id=FREE;fat1++;fat2++;}/*创建根目录文件root,将数据区的第一块分配给根目录区在给磁盘上创建两个特殊的目录项:".","..",除了文件名之外,其它都相同*/p+=BLOCKSIZE*5;root=(fcb *)p;strcpy(root->filename,".");strcpy(root->exname,"di");root->attr ibute=40;now=(time_t *)malloc(sizeof(time_t));time(now);nowtime=localtime(now);root->time=nowtime->tm_hour*2048+nowtime->tm_min*32+nowtime->tm_sec/2;root->date=(nowtime->tm_year-80)*512+(nowtime->tm_mon+1)*32+nowtime->tm_mday; root->first=5;root->length=2*sizeof(fcb);root++;strcpy(root->filename,"..");strcpy(root->exname,"di");root->attr ibute=40;time(now);nowtime=localtime(now);root->time=nowtime->tm_hour*2048+nowtime->tm_min*32+nowtime->tm_sec/2;root->date=(nowtime->tm_year-80)*512+(nowtime->tm_mon+1)*32+nowtime->tm_mday; root->first=5;root->length=2*sizeof(fcb);root++;for(i=2;i<BLOC KSIZE*2/sizeof(fcb);i++,root++){root->filename[0]='\0';}fp=fopen(filename,"w");b0->startblock=p+BLOCKSIZE*4;fwrite(myvhard,SIZE,1,fp);free(now);fclose(fp);}/**//*原型声明: void my_exitsys()功能描述:退出文件系统输入:无输出:无函数功能实现算法描述:*/void my_exitsys(){FILE *fp;fcb *rootfcb;char text[MAX_TXT_SIZE];while(curfd)curfd=my_close(curfd);if(openfilelist[curfd].fcbstate){openfilelist[curfd].count=0;do_read(curfd,openfilelist[curfd].length,text);rootfcb=(char *)text;rootfcb->length=openfilelist[curfd].length;openfilelist[curfd].count=0;do_write(curfd,text,openfilelist[curfd].length,2);}fp=fopen(filename,"w");fwrite(myvhard,SIZE,1,fp);free(myvhard);fclose(fp);}/*原型声明: int do_read(int fd,int len,char *text)功能描述:实际读文件函数,读出指定文件中从指定指针开始的长度为len的内容到用户空间的text中输入:fd open()函数的返回值,文件的描述符len 要求从文件中读出的字节数text 指向存放读出数据的用户区地址输出:实际读出的字节数函数功能实现算法描述:*/int do_read(int fd,int len,char *text){unsigned char *buf;unsigned short bknum;int off,i,lentmp;unsigned char *bkptr;char *txtmp,*p;fat *fat1,*fatptr;fat1=(fat *)(myvhard+BLOC KSIZE);lentmp = len;txtmp=text;/*申请1024B空间作为缓冲区buffer*/buf=(unsigned char *)malloc(1024);if(buf==NULL){printf("malloc failed!\n");return -1;}off = openfilelist[fd].count;bknum = openfilelist[fd].first;fatptr = fat1+bknum;while(off >= BLOC KSIZE){off=off-BLOCKSIZE;bknum=fatptr->id;fatptr=fat1+bknum;if(bknum == END){printf("Error,the block is not exist.\n");return -1;}}bkptr=(unsigned char *)(myvhard+bknum*BLOCKSIZE);//strncpy(buf,bkptr,BLOCKSIZE);for(i=0;i<BLOC KSIZE;i++){buf[i]=bkptr[i];}while(len > 0){if(BLOCKSIZE-off > len){//strncpy(txtmp,buf+off,len);//len=len-len;//openfilelist[fd].count+=len;//off+=len;for(p=buf+off;len>0;p++,txtmp++){*txtmp=*p;len--;off++;openfilelist[fd].count++;}}else{//strncpy(txtmp,buf+off,BLOCKSIZE-off);//len=len-(BLOCKSIZE-off);//openfilelist[fd].count+=(BLOCKSIZE-off);for(p=buf+off;p<buf+BLOCKSIZE;p++,txtmp++){*txtmp=*p;len--;openfilelist[fd].count++;}off=0;//txtmp+=(BLOCKSIZE-off);bknum =fatptr->id;fatptr = fat1+bknum;bkptr=(unsigned char *)(myvhard+bknum*BLOCKSIZE);//strncpy(buf,bkptr,BLOCKSIZE);for(i=0;i<BLOC KSIZE;i++){buf[i]=bkptr[i];}}}free(buf);return lentmp-len;}/**//*原型声明: int my_read(int fd,int len) 功能描述:读文件函数输入:fd 打开文件的idlen 要读出字符的个数输出:返回实际读的字符的个数函数功能实现算法描述:*/int my_read(int fd,int len){char text[MAX_TXT_SIZE];if(fd > MAX_OPEN_FILE){printf("The File is not exist!\n");return -1;}openfilelist[curfd].count=0;if(do_read(fd,len,text)>0){text[len]='\0';printf("%s\n",text);}else{printf("Read Error!\n");return -1;}return len;}/**//*原型声明: int do_write(int fd,char *text,int len,char wstyle) 功能描述:实际写文件函数输入:fd 当前打开的文件的idtext 指向要写入的内容的指针len 本次要写入字节数wstyle写方式输出:实际写入的字节数函数功能实现算法描述:*/int do_write(int fd,char *text,int len,char wstyle){unsigned char *buf;unsigned short bknum;int off,tmplen=0,tmplen2=0,i,rwptr;unsigned char *bkptr,*p;char *txtmp,flag=0;fat *fat1,*fatptr;fat1=(fat *)(myvhard+BLOC KSIZE);txtmp=text;/*申请临时1024B的buffer*/buf=(unsigned char *)malloc(BLOCKSIZE);if(buf==NULL){printf("malloc failed!\n");return -1;}rwptr = off = openfilelist[fd].count;bknum = openfilelist[fd].first;fatptr=fat1+bknum;while(off >= BLOC KSIZE ){off=off-BLOCKSIZE;bknum=fatptr->id;if(bknum == END){bknum=fatptr->id=findFree();if(bknum==END) retur n -1;fatptr=fat1+bknum;fatptr->id=END;}fatptr=fat1+bknum;}fatptr->id=END;bkptr=(unsigned char *)(myvhard+bknum*BLOCKSIZE); while(tmplen<len){for(i=0;i<BLOC KSIZE;i++){buf[i]=0;}//if(off)//{for(i=0;i<BLOC KSIZE;i++){buf[i]=bkptr[i];tmplen2++;if(tmplen2==openfilelist[curfd].length)break;}//}//else//{//for(i=0;i<BLOCKSIZE;i++)//{// buf[i]=0;//}//}for(p=buf+off;p<buf+BLOCKSIZE;p++){*p=*txtmp;tmplen++;txtmp++;off++;if(tmplen==len)break;/*if((*p)==NULL){break;}*/}for(i=0;i<BLOC KSIZE;i++){bkptr[i]=buf[i];}openfilelist[fd].count=rwptr+tmplen;if(off>=BLOCKSIZE){off=off-BLOCKSIZE;bknum=fatptr->id;if(bknum==END){bknum=fatptr->id=findFree();if(bknum==END) retur n -1;fatptr=fat1+bknum;fatptr->id=END;}fatptr=fat1+bknum;bkptr=(unsigned char *)(myvhard+bknum*BLOCKSIZE);}}free(buf);if(openfilelist[fd].count>openfilelist[fd].length){openfilelist[fd].length=openfilelist[fd].count;}openfilelist[fd].fcbstate=1;return tmplen;}/**//*原型声明: unsigned short findFree()功能描述:寻找下一个空闲盘块输入:无输出:返回空闲盘块的id函数功能实现算法描述:*/unsigned short findFree(){unsigned short i;fat *fat1,*fatptr;fat1=(fat *)(myvhard+BLOC KSIZE);for(i=6; i<END; i++){fatptr=fat1+i;if(fatptr->id == FREE){return i;}}printf("Error,Can't find free block!\n"); return END;}/*原型声明: int findFreeO()功能描述:寻找空闲文件表项输入:无输出:返回空闲文件表项的id 函数功能实现算法描述:*/int findFreeO(){int i;for(i=0;i<MAX_OPEN_FILE;i++){if(openfilelist[i].free==0){return i;}}printf("Error,open too many files!\n"); return -1;}/**//*原型声明: int my_wr ite(int fd)功能描述:写文件函数输入:fd 打开文件的id输出:返回实际写的长度函数功能实现算法描述:*/int my_wr ite(int fd){int wstyle=0,wlen=0;fat *fat1,*fatptr;unsigned short bknum;unsigned char *bkptr;char text[MAX_TXT_SIZE];fat1=(fat *)(myvhard+BLOC KSIZE);if(fd>MAX_OPEN_FILE){printf("The file is not exist!\n");return -1;}while(wstyle<1||wstyle>3){printf("Please enter the number of wr ite style:\n1.cut wr ite\t2.cover write\t3.add write\n");scanf("%d",&wstyle);getchar();switch(wstyle){case 1://截断写{bknum=openfilelist[fd].first;fatptr=fat1+bknum;while(fatptr->id!=END){bknum=fatptr->id;fatptr->id=FREE;fatptr=fat1+bknum;}fatptr->id=FREE;bknum=openfilelist[fd].first;fatptr=fat1+bknum;fatptr->id=END;openfilelist[fd].length=0;openfilelist[fd].count=0;break;}case 2://覆盖写{openfilelist[fd].count=0;break;}case 3://追加写{bknum=openfilelist[fd].first;fatptr=fat1+bknum;openfilelist[fd].count=0;while(fatptr->id!=END){bknum=fatptr->id;fatptr=fat1+bknum;openfilelist[fd].count+=BLOCKSIZE;}bkptr=(unsigned char *)(myvhard+bknum*BLOCKSIZE);while(*bkptr !=0){bkptr++;openfilelist[fd].count++;}break;}default:break;}}printf("please input write data:\n");gets(text);if(do_write(fd,text,str len(text),wstyle)>0){wlen+=strlen(text);}else{return -1;}if(openfilelist[fd].count>openfilelist[fd].length){openfilelist[fd].length=openfilelist[fd].count;}openfilelist[fd].fcbstate=1;return w len;}/*原型声明: void my_mkdir(char *dirname)功能描述:创建子目录函数,在当前目录下创建名为dirname的目录输入:dirname 指向新建目录的名字的指针输出:无函数功能实现算法描述:*/void my_mkdir(char *dirname){fcb *dirfcb,*pcbtmp;int rbn,i,fd;unsigned short bknum;char text[MAX_TXT_SIZE],*p;time_t *now;struct tm *nowtime;/*将当前的文件信息读到text中rbn 是实际读取的字节数*/openfilelist[curfd].count=0;rbn = do_read(curfd,openfilelist[curfd].length,text);dirfcb=(fcb *)text;/*检测是否有相同的目录名*/for(i=0;i<rbn/sizeof(fcb);i++){if(strcmp(dirname,dirfcb->filename)==0){printf("Error,the dirname is alr eady exist!\n");return -1;}dirfcb++;}/*分配一个空闲的打开文件表项*/dirfcb=(fcb *)text;for(i=0;i<rbn/sizeof(fcb);i++){if(strcmp(dirfcb->filename,"")==0)break;dirfcb++;}openfilelist[curfd].count=i*sizeof(fcb);fd=findFreeO();if(fd<0){return -1;}/*寻找空闲盘块*/bknum = findFree();if(bknum == END ){return -1;}pcbtmp=(fcb *)malloc(sizeof(fcb));now=(time_t *)malloc(sizeof(time_t));//在当前目录下新建目录项pcbtmp->attribute=0x30;time(now);nowtime=localtime(now);pcbtmp->time=nowtime->tm_hour*2048+nowtime->tm_min*32+nowtime->tm_sec/2; pcbtmp->date=(nowtime->tm_year-80)*512+(nowtime->tm_mon+1)*32+nowtime->tm_mday; strcpy(pcbtmp->filename,dirname);strcpy(pcbtmp->exname,"di");pcbtmp->first=bknum;pcbtmp->length=2*sizeof(fcb);openfilelist[fd].attribute=pcbtmp->attribute;openfilelist[fd].count=0;openfilelist[fd].date=pcbtmp->date;strcpy(openfilelist[fd].dir[fd],openfilelist[curfd].dir[curfd]);p=openfilelist[fd].dir[fd];while(*p!='\0')p++;strcpy(p,dirname);while(*p!='\0') p++;*p='\\';p++;*p='\0';openfilelist[fd].dirno=openfilelist[curfd].first;openfilelist[fd].diroff=i;strcpy(openfilelist[fd].exname,pcbtmp->exname);strcpy(openfilelist[fd].filename,pcbtmp->filename);openfilelist[fd].fcbstate=1;openfilelist[fd].first=pcbtmp->first;openfilelist[fd].length=pcbtmp->length;openfilelist[fd].free=1;openfilelist[fd].time=pcbtmp->time;openfilelist[fd].topenfile=1;do_write(curfd,(char *)pcbtmp,sizeof(fcb),2);pcbtmp->attribute=0x28;time(now);nowtime=localtime(now);pcbtmp->time=nowtime->tm_hour*2048+nowtime->tm_min*32+nowtime->tm_sec/2; pcbtmp->date=(nowtime->tm_year-80)*512+(nowtime->tm_mon+1)*32+nowtime->tm_mday; strcpy(pcbtmp->filename,".");strcpy(pcbtmp->exname,"di");pcbtmp->first=bknum;pcbtmp->length=2*sizeof(fcb);do_write(fd,(char *)pcbtmp,sizeof(fcb),2);pcbtmp->attribute=0x28;time(now);nowtime=localtime(now);pcbtmp->time=nowtime->tm_hour*2048+nowtime->tm_min*32+nowtime->tm_sec/2; pcbtmp->date=(nowtime->tm_year-80)*512+(nowtime->tm_mon+1)*32+nowtime->tm_mday; strcpy(pcbtmp->filename,"..");strcpy(pcbtmp->exname,"di");pcbtmp->first=openfilelist[curfd].first;pcbtmp->length=openfilelist[curfd].length;do_write(fd,(char *)pcbtmp,sizeof(fcb),2);openfilelist[curfd].count=0;do_read(curfd,openfilelist[curfd].length,text);pcbtmp=(fcb *)text;pcbtmp->length=openfilelist[curfd].length;my_close(fd);openfilelist[curfd].count=0;do_write(curfd,text,pcbtmp->length,2);}/**//*原型声明: void my_ls()功能描述:显示目录函数输入:无输出:无函数功能实现算法描述:*/void my_ls(){fcb *fcbptr;int i;char text[MAX_TXT_SIZE];unsigned short bknum;openfilelist[curfd].count=0;do_read(curfd,openfilelist[curfd].length,text);fcbptr=(fcb *)text;for(i=0;i<(int)(openfilelist[curfd].length/sizeof(fcb));i++){if(fcbptr->filename[0]!='\0'){if(fcbptr->attr ibute&0x20){printf("%s\\\t\t<DIR>\t\t%d/%d/%d\t%02d:%02d:%02d\n",fcbptr->filename,((fcbptr->date)>>9)+1980,((fcbptr->date)>>5) &0x000f,(fcbptr->date)&0x001f,fcbptr->time>>11,(fcbptr->time>>5)&0x003f,fcbptr->time&0x001f*2);}else{printf("%s.%s\t\t%dB\t\t%d/%d/%d\t%02d:%02d:%02d\t\n",fcbptr->filename,fcbptr->exname,fcbptr->length,((fcbptr->da te)>>9)+1980,(fcbptr->date>>5)&0x000f,fcbptr->date&0x1f,fcbptr->time>>11,(fcbptr->time>>5)&0x3f,fcbptr->time&0x1f*2);}}fcbptr++;}openfilelist[curfd].count=0;}/**//*原型声明: void my_rmdir(char *dir name)功能描述:删除子目录函数输入:dirname 指向新建目录的名字的指针输出:无函数功能实现算法描述:*/void my_rmdir(char *dir name){int rbn,fd;char text[MAX_TXT_SIZE];fcb *fcbptr,*fcbtmp,*fcbtmp2;unsigned short bknum;int i,j;fat *fat1,*fatptr;if(strcmp(dirname,".")==0 || strcmp(dirname,"..")==0) {printf("Error,can't remove this directory.\n");return -1;}fat1=(fat *)(myvhard+BLOC KSIZE);openfilelist[curfd].count=0;rbn=do_read(curfd,openfilelist[curfd].length,text); fcbptr=(fcb *)text;for(i=0;i<rbn/sizeof(fcb);i++){if(strcmp(dirname,fcbptr->filename)==0){break;}fcbptr++;}if(i >= rbn/sizeof(fcb)){printf("Error,the directory is not exist.\n");return -1;}bknum=fcbptr->first;fcbtmp2=fcbtmp=(fcb *)(myvhard+bknum*BLOCKSIZE);for(j=0;j<fcbtmp->length/sizeof(fcb);j++){if(strcmp(fcbtmp2->filename,".") && strcmp(fcbtmp2->filename,"..") && fcbtmp2->filename[0]!='\0') {printf("Error,the directory is not empty.\n");return -1;}fcbtmp2++;}while(bknum!=END){fatptr=fat1+bknum;bknum=fatptr->id;fatptr->id=FREE;}strcpy(fcbptr->filename,"");strcpy(fcbptr->exname,"");fcbptr->first=END;openfilelist[curfd].count=0;do_write(curfd,text,openfilelist[curfd].length,2);}/*原型声明: int my_open(char *filename)功能描述:打开文件函数输入:filename 指向要打开的文件的名字的指针输出:返回打开的文件的id函数功能实现算法描述:*/int my_open(char *filename){int i,fd,rbn;char text[MAX_TXT_SIZE],*p,*fname,*exname;fcb *fcbptr;char exnamed=0;fname=strtok(filename,".");exname=strtok(NULL,".");if(!exname){exname=(char *)malloc(3);strcpy(exname,"di");exnamed=1;}for(i=0;i<MAX_OPEN_FILE;i++){if(strcmp(openfilelist[i].filename,filename)==0 &&strcmp(openfilelist[i].exname,exname)==0&& i!=curfd) {printf("Error,the file is already open.\n");return -1;}}openfilelist[curfd].count=0;rbn=do_read(curfd,openfilelist[curfd].length,text);fcbptr=(fcb *)text;for(i=0;i<rbn/sizeof(fcb);i++){if(strcmp(filename,fcbptr->filename)==0 && strcmp(fcbptr->exname,exname)==0){break;}fcbptr++;}if(i>=rbn/sizeof(fcb)){printf("Error,the file is not exist.\n");return curfd;}if(exnamed){free(exname);}fd=findFreeO();if(fd==-1){return -1;}strcpy(openfilelist[fd].filename,fcbptr->filename); strcpy(openfilelist[fd].exname,fcbptr->exname); openfilelist[fd].attribute=fcbptr->attribute;openfilelist[fd].count=0;openfilelist[fd].date=fcbptr->date;openfilelist[fd].first=fcbptr->first;openfilelist[fd].length=fcbptr->length;openfilelist[fd].time=fcbptr->time;openfilelist[fd].father=curfd;openfilelist[fd].dirno=openfilelist[curfd].first; openfilelist[fd].diroff=i;openfilelist[fd].fcbstate=0;openfilelist[fd].free=1;openfilelist[fd].topenfile=1;strcpy(openfilelist[fd].dir[fd],openfilelist[curfd].dir[curfd]); p=openfilelist[fd].dir[fd];while(*p!='\0')p++;strcpy(p,filename);while(*p!='\0') p++;if(openfilelist[fd].attribute&0x20){*p='\\';p++; *p='\0';}else{*p='.';p++;strcpy(p,openfilelist[fd].exname);}return fd;}/**//*原型声明: int my_close(int fd)功能描述:关闭文件函数输入:fd 打开文件的id输出:返回fd的father的id函数功能实现算法描述:*/int my_close(int fd){fcb *fafcb;char text[MAX_TXT_SIZE];int fa;/*检查fd的有效性*/if(fd > MAX_OPEN_FILE || fd<=0){printf("Error,the file is not exist.\n");return -1;}fa=openfilelist[fd].father;if(openfilelist[fd].fcbstate){fa=openfilelist[fd].father;openfilelist[fa].count=0;do_read(fa,openfilelist[fa].length,text);fafcb=(fcb *)(text+sizeof(fcb)*openfilelist[fd].diroff);fafcb->attribute=openfilelist[fd].attr ibute;fafcb->date=openfilelist[fd].date;fafcb->first=openfilelist[fd].first;fafcb->length=openfilelist[fd].length;fafcb->time=openfilelist[fd].time;strcpy(fafcb->filename,openfilelist[fd].filename);strcpy(fafcb->exname,openfilelist[fd].exname);openfilelist[fa].count=0;do_write(fa,text,openfilelist[fa].length,2);}openfilelist[fd].attribute=0;openfilelist[fd].count=0;openfilelist[fd].date=0;strcpy(openfilelist[fd].dir[fd],"");strcpy(openfilelist[fd].filename,"");strcpy(openfilelist[fd].exname,"");openfilelist[fd].length=0;openfilelist[fd].time=0;openfilelist[fd].free=0;openfilelist[fd].topenfile=0;return fa;}/**//*原型声明: void my_cd(char *dirname) 功能描述:更改当前目录函数输入:dirname 指向目录名的指针输出:无函数功能实现算法描述:*/void my_cd(char *dirname){char *p,text[MAX_TXT_SIZE];int fd,i;p=strtok(dirname,"\\");if(strcmp(p,".")==0)return;if(strcmp(p,"..")==0){fd=openfilelist[curfd].father;my_close(curfd);curfd=fd;ptrcurdir=&openfilelist[curfd];return;}if(strcmp(p,"r oot")==0){for(i=1;i<MAX_OPEN_FILE;i++){if(openfilelist[i].free)my_close(i);}ptrcurdir=&openfilelist[0];curfd=0;p=strtok(NULL,"\\");}while(p){fd=my_open(p);if(fd>0){ptrcurdir=&openfilelist[fd];curfd=fd;}elsereturn -1;p=strtok(NULL,"\\");}}/**//*原型声明: void my_create(char *filename)功能描述:创建文件函数输入:filename 指向文件名的指针输出:无函数功能实现算法描述:*/void my_create(char *filename){char *fname,*exname,text[MAX_TXT_SIZE];int fd,rbn,i;fcb *filefcb,*fcbtmp;time_t *now;struct tm *nowtime;unsigned short bknum;fat *fat1,*fatptr;fat1=(fat *)(myvhard+BLOC KSIZE);fname=strtok(filename,".");exname=strtok(NULL,".");if(strcmp(fname,"")==0){printf("Error,creating file must have a right name.\n");return -1;}if(!exname){printf("Error,creating file must have a extern name.\n");return -1;}openfilelist[curfd].count=0;rbn=do_read(curfd,openfilelist[curfd].length,text);filefcb=(fcb *)text;for(i=0;i<rbn/sizeof(fcb);i++){if(strcmp(fname,filefcb->filename)==0 && strcmp(exname,filefcb->exname)==0){printf("Error,the filename is already exist!\n");return -1;}filefcb++;}filefcb=(fcb *)text;for(i=0;i<rbn/sizeof(fcb);i++){if(strcmp(filefcb->filename,"")==0)break;filefcb++;}openfilelist[curfd].count=i*sizeof(fcb);bknum=findFree();if(bknum==END){return -1;}fcbtmp=(fcb *)malloc(sizeof(fcb));now=(time_t *)malloc(sizeof(time_t));fcbtmp->attribute=0x00;time(now);nowtime=localtime(now);fcbtmp->time=nowtime->tm_hour*2048+nowtime->tm_min*32+nowtime->tm_sec/2;fcbtmp->date=(nowtime->tm_year-80)*512+(nowtime->tm_mon+1)*32+nowtime->tm_mday; strcpy(fcbtmp->filename,fname);。
操作系统课程设计:文件系统一、引言文件系统是操作系统中的一个重要组成部分,负责管理计算机存储设备上的文件和目录。
一个高效可靠的文件系统对于操作系统和用户来说都至关重要。
在操作系统课程中,设计一个文件系统是一项重要的任务,可以帮助学生深入了解文件系统的原理和实现细节。
本文档将介绍一个简单的文件系统设计,旨在帮助初学者理解文件系统的基本概念和工作原理。
我们将首先介绍文件系统的基本概念,然后讨论文件系统的设计思路和关键组成部分。
最后,我们将讨论如何实现和测试文件系统。
二、文件系统的基本概念文件系统是操作系统提供的一种存储管理机制,用于将文件组织成有层次的结构并提供对文件的访问和管理。
在一个文件系统中,文件被组织成目录(或文件夹)的层次结构,用户可以使用文件路径来访问文件和目录。
文件系统通常提供以下功能: - 文件和目录的创建、删除和重命名 - 文件和目录的读取和写入 - 文件和目录的权限管理 - 文件的共享和保护 - 文件的存储管理三、设计思路在设计文件系统时,需要考虑以下几个关键方面:1. 文件系统的组织结构文件系统可以采用不同的组织结构,常见的包括层次结构、网络结构和日志结构。
在设计文件系统时,需要根据具体需求选择合适的结构。
2. 文件和目录的管理文件系统需要提供对文件和目录的管理功能,包括创建、删除、重命名和移动等操作。
此外,还需要支持文件和目录的权限管理,确保只有授权用户可以进行相应操作。
3. 文件的存储管理文件系统需要负责将文件存储在磁盘或其他存储设备上,并提供高效的读写操作。
存储管理的关键是如何将文件划分为适当大小的块并将它们存储在存储设备上。
4. 文件的共享和保护文件系统需要支持文件的共享和保护。
共享可以使多个用户同时访问同一文件,保护则确保只有合法用户可以进行读写操作。
四、文件系统的关键组成部分一个典型的文件系统通常由以下几个关键组成部分构成:1. 文件控制块(FCB)文件控制块是文件系统中一个重要的数据结构,用于记录文件的相关信息,包括文件名、大小、权限和存储位置等。
课程设计报告( 20 --20 年度第学期)课程名称:操作系统实验课设题目:文件系统的实现院系:控制与计算机工程学院班级:姓名:指导教师:设计周数:一周成绩:20 年月日设计报告内容一、需求分析用C或C++编写和调试一个文件系统,功能使用命令行的方式实现。
模拟文件管理的工作过程。
加深理解文件系统的内部功能和内部实现。
用内存模拟磁盘用结构体数组描述个不同的磁盘区域。
磁盘的存取单元是磁盘块,一个盘块的大小是64字节。
每个目录项16个字节,目录项下只允许建立4个子目录或者文件。
i-node位图1块64个字节,共512位,可以描述512个i-node的使用情况。
i-node的长度是16字节。
文件超过两个盘块会用到一级索引。
每个以及索引盘块(64字节)可以包含16个盘块号。
文件包含目录文件和文本文件。
实现Format,Mkfile,Mkdir,Cd,Delfile,Deldir,Dir,Copy,Open,Viewinodebitmap,V iewblockbitmap等功能。
二、整体功能及设计(功能划分及流程图)1、数据结构:struct DirectoryEntry{ //目录项char name[8]; //文件或目录名int dirid; //目录标志(0为文件,1为目录)int inodenumber; //i-node编号};struct DirectoryEntryInBlock{DirectoryEntry de[4]; //每个目录项大小为16字节,64字节空间最多可以存储4个目录项int num; //磁盘块存储的目录项数目};struct indexaddressstruct{int indexaddress[16]; //每个索引块大小为4字节,64字节空间最多可以存储16个索引块号int num; //索引块存储的索引数目};union Block{ //单个盘块64个字节大小可以存储文件内容或者存储目录项或者存储索引块号char space[64]; //空间大小为64个字节用于存储文件内容DirectoryEntryInBlock deib;indexaddressstruct ias;};struct inodeStruct{ //i-node结构int blockamount; //盘块数int directblockaddress1,directblockaddress2; //直接盘块地址*2int stairindexaddress; //一级索引地址};struct DiskBlock{ //磁盘布局DirectoryEntry rootdirectory[4]; //根目录,最多4个目录项char inodebitmap[512]; //512个i-node状态char blockbitmap[1024]; //1024个磁盘块状态inodeStruct inode[512]; //512个i-node存储区Block datablock[1024]; //数据块存储区};static DiskBlock db; //全局磁盘变量int rootdirectoryamount; //用于记录根目录的使用数目,最大为4int inodeamount; //用于记录i-node的使用数目,最大为512int datablockamount; //用于记录数据块的使用数目,最大为1024int spaceamount; //用于记录数据块中64位字节的使用数目,最大为64DirectoryEntry filelist[500]; //用于记录文件方便遍历检索DirectoryEntry directorylist[500]; //用于记录目录方便int fileamount; //用于记录文件数目int directoryamount; //用于记录目录的数目char localposition[8]; //用于记录当前位置2、文件系统相关图(1)文件系统简单结构图如图1所示。
计算机系综合性实验实验报告课程名称操作系统实验报告一个简单的文件系统的详细设计一个简单的文件系统的详细设计一、实验目的(1)阅读并调试一个简单的文件系统,模拟文件管理的工作过程。
从而对各种文件操作命令的实质内容和执行过程有比较深入的了解。
(2)了解设计一个n个用户的文件系统,每个用户可以保存M个文件。
用户在一次运行中只能打开一个文件,对文件必须设置保护措施,且至少有create、delete、open、close、read、write等命令。
二、实验要求1、根据流程图阅读所给文件系统源程序,并对源程序加以注释(注释量达70%以上)。
2、修改、完善该系统,指出程序的bug。
三、文件系统功能设计1. 功能设计该文件系统是一个多用户、多任务的文件系统。
对用户和用户的文件数目并没有上限。
也就是说该系统允许任何用户申请空间,而且在其目录下的文件数目并不做任何的限制。
该系统可以支持的操作命令如下:①bye——用户注销命令。
当使用该命令时,用户退出系统,注销该用户功能设计并回到登陆界面。
命令格式:bye②close——删除用户注册信息命令。
执行该命令后,用户在系统中的所有信息,包括该用户目录下的所有文件都被删除。
命令执行完成后返回登陆界面。
命令格式:close③create——在当前目录下创建一个文件,且该文件不能跟当前已有的文件重名。
该文件的管理信息登记在用户文件信息管理模块中。
执行完该命令后回到执行命令行。
命令格式:create>file1其中:“>”符为提示符,file1为要创建的文件名。
④delete——删除当前用户目录下的一个文件,命令执行完毕返回至命令行。
命令格式:delete>file1其中:file1为要删除的文件名。
⑤list——显示当前注册目录下的所有文件信息,包括文件名、文件长度、文件操作权限。
命令格式:list⑥chmod——改变某个文件的执行权限,但前提是该文件是该用户目录下的文件。
操作系统课程设计报告小组小组成员:一、课程设计概述:1、题目:简单文件系统的实现2、实现容(1)在存中开辟一个虚拟磁盘空间作为文件存储分区,在其上实现一个简单的基于多级目录的单用户单任务系统中的文件系统。
在退出该文件系统的使用时,应将该虚拟文件系统以一个Windows 文件的方式保存到磁盘上,以便下次可以再将它恢复到存的虚拟磁盘空间中。
(2)文件存储空间的分配可采用显式分配或其他的方法。
(3)空闲磁盘空间的管理可选择位示图或其他的方法。
如果采用位示图来管理文件存储空间,并采用显式分配方式,则可以将位示图合并到FAT中。
(4)文件目录构造采用多级目录构造。
为了简单起见,可以不使用索引结点,其中的每个目录项应包含文件名、物理地址、长度等信息,还可以通过目录项实现对文件的读和写的保护。
(5)要求提供以下操作命令:●my_format:对文件存储器进展格式化,即按照文件系统的构造对虚拟磁盘空间进展布局,并在其上创立根目录以及用于管理文件存储空间等的数据构造。
●my_mkdir:用于创立子目录。
●my_rmdir:用于删除子目录。
●my_ls:用于显示目录中的容。
●my_cd:用于更改当前目录。
●my_create:用于创立文件。
●my_open:用于翻开文件。
●my_close:用于关闭文件。
●my_write:用于写文件。
●my_read:用于读文件。
●my_rm:用于删除文件。
●my_e*itsys:用于退出文件系统。
二、设计思路〔主要算法描述、程序流程图等〕:1.系统主函数main()〔1〕对应命令:无〔2〕命令调用格式:无〔3〕函数设计格式:void main()〔4〕功能:系统主函数〔5〕输入:无〔6〕输出:无〔7〕函数需完成的工作:①对前面定义的全局变量进展初始化;②调用startsys()进入文件系统;③列出文件系统提供的各项功能及命令调用格式;④显示命令行提示符,等待用户输入命令;⑤将用户输入的命令保存到一个buf中;⑥对buf中的容进展命令解析,并调用相应的函数执行用户键入的命令;⑦如果命令不是"my_e*itsys〞,则命令执行完毕后转④。
操作系统课程设计为LINUX设计一个简单的二级文件系统一.项目概述本课程设计旨在通过设计一个简单的多用户文件系统,加深学生对文件系统内部功能及内部实现的理解,并提高学生的程序设计能力、算法设计质量与程序设计素质。
二.设计题目为LINUX设计一个简单的二级文件系统,要求实现以下命令:Login用户登录、Dir列文件目录、Create创建文件、Delete删除文件、Open打开文件、Close关闭文件、Read读文件、Write写文件。
列目录时需包括文件名、物理地址、保护码和文件长度。
源文件需进行读写保护。
三.开发语言及实现平台或实验环境本课程设计的开发语言为C语言,实现平台为Linux操作系统。
学生需要在规定时间内完成程序的编写和调试,并书写课程设计报告。
四.时间安排1月17日布置课程设计任务,学生需要自行查阅资料并准备程序。
1月18日至1月20日,学生需要在机房上机调试程序,并书写课程设计报告。
1月21日上午,学生需要提交课程设计报告及相关文档。
每位学生应独立完成各自的任务,每天至少在设计室工作半天。
五.具体要求1.课程设计报告应按统一通用格式书写,具体格式要求请在网络上查阅。
2.指导教师和教研室主任(或责任教师)需要在规定时间内签署相应的文件。
设计目的:本设计旨在开发一款能够实现某种功能的程序,为用户提供便利。
设计内容:5.1.该程序将包括两个主要功能:A和B。
A功能将执行某种操作,而B功能将提供用户界面,使其能够轻松地使用A功能。
5.2.此外,该程序还将包括其他辅助功能,例如C和D。
这些功能将提高程序的可用性和实用性。
任务:该程序的主要任务是为用户提供一种方便、高效的解决方案,使其能够更轻松地实现某种目标。
主程序流程图:程序的主要流程将包括以下步骤:用户打开程序,选择所需的功能,程序执行相应的操作,最终将结果返回给用户。
程序设计:6.1.在程序设计方面,我们将采用一种灵活、可扩展的架构,以便能够轻松地添加新的功能和模块。
操作系统课程设计报告小组成员:、课程设计概述:1 题目:简单文件系统的实现 2、实现内容(1) 在内存中开辟一个虚拟磁盘空间作为文件存储分区, 在其上实现一个简单的基于多 级目录的单用户单任务系统中的文件系统。
在退出该文件系统的使用时, 应将该虚拟文件系 统以一个 Windows 文件的方式保存到磁盘上,以便下次可以再将它恢复到内存的虚拟磁盘 空间中。
(2) 文件存储空间的分配可采用显式链接分配或其他的办法。
(3) 空闲磁盘空间的管理可选择位示图或其他的办法。
如果采用位示图来管理文件存储 空间,并采用显式链接分配方式,那么可以将位示图合并到FAT 中。
(4) 文件目录结构采用多级目录结构。
为了简单起见,可以不使用索引结点,其中的每 个目录项应包含文件名、 物理地址、长度等信息,还可以通过目录项实现对文件的读和写的 保护。
(5) 要求提供以下操作命令:my_format : 对文件存储器进行格式化,即按照文件系统的结构对虚拟磁盘空 间进行布局,并在其上创建根目录以及用于管理文件存储空间等的数据结构。
my_mkdir : 用于创建子目录。
my_rmdir : 用于删除子目录。
my_create : 用于创建文件。
my_ope n :用于打开文件。
my_close : 用于关闭文件。
my_rm : 用于删除文件。
my_exitsys : 用于退出文件系统。
二、设计思路 (主要算法描述、程序流程图等 ) 1 . 系统主函数 main() (1) 对应命令:无 (2) 命令调用格式:无 (3)函数设计格式: void main() (4) 功能:系统主函数 (5) 输入:无 (6) 输出:无(7) 函数需完成的工作:① 对前面定义的全局变量进行初始化; ② 调用 startsys() 进入文件系统;小组编号:my_ls : 用于显示目录中的内容my_cd : 用于更改当前目录my_write : 用于写文件。
my_read: 用于读文件。
③ 列出文件系统提供的各项功能及命令调用格式; ④ 显示命令行提示符,等待用户输入命令; ⑤ 将用户输入的命令保存到一个buf 中;⑥ 对 buf 中的内容进行命令解析,并调用相应的函数执行用户键入的命令; ⑦ 如果命令不是 " my_exitsys" ,则命令执行完毕后转④。
2.进入文件系统函数 startsys() (1) 对应命令:无 (2) 命令调用格式:无 (3)函数设计格式: void startsys()(4) 功能:由 main() 函数调用,进入并初始化我们所建立的文件系统,以供用户使用。
(5) 输入:无 (6) 输出:无。
(7) 函数需完成的工作: ①申请虚拟磁盘空间;② 使用c 语言的库函数fopen()打开myfsys 文件:若文件存在,则转③;若文件不存在, 则创建之,转⑤ ③ 使用 c 语言的库函数 fread() 读入 myfsys 文件内容到用户空间中的一个缓冲区中,并判 断其开始 的8个字节内容是否为“ 10101010” (文件系统魔数),如果是,则转④;否则转 ⑤; ④ 将上述缓冲区中的内容复制到内存中的虚拟磁盘空间中;转⑦⑤ 在屏幕上显示“ myfsys 文件系统不存在,现在开始创建文件系统”信息,并调用 my_format() 对 ①中申请到的虚拟磁盘空间进行格式化操作。
转⑥; ⑥ 将虚拟磁盘中的内容保存到myfsys 文件中;转⑦⑦ 使用 c 语言的库函数 fclose( 关闭 myfsys 文件;⑧ 初始化用户打开文件表,将表项 0分配给根目录文件使用,并填写根目录文件的相关信 息,由于根目录没有上级目录,所以表项中的 dirno 和 diroff 分别置为 5 (根目录所在起始块号)和0;并将ptrcurdir指针指向该用户打开文件表项。
⑨ 将当前目录设置为根目录。
3. 磁盘格式化函数 my_format() (1) 对应命令: my_format (2) 命令调用格式: my_format (3) 函数设计格式: void my_format()(4) 功能:对虚拟磁盘进行格式化,布局虚拟磁盘,建立根目录文件 (或根目录区 )(5) 输入:无 (6) 输出:无。
(7) 函数需完成的工作:开始的 8 个字节是文件系统的魔数, 记为“ 10101010”; FAT 表大小及位置、根目录大小及位置、盘块大小、 FAT 表,用于记录文件所占据的磁盘块及管理虚拟磁盘块的分配,每个 FAT 占据两个磁盘块;对于每个 FAT 中,前面5个块设置为已分配,后面 995个块设 置为空① 将虚拟磁盘第一个块作为引导块 在之后写入文件系统的描述信息,如 盘块数量、数据区开始位置等信息;② 在引导块后建立两张完全一样的闲;③在第二张FAT后创建根目录文件root,将数据区的第1块(即虚拟磁盘的第6块)分配字段完全相同。
4. 更改当前目录函数my_cd()(1) 对应命令:my_cd(2) 命令调用格式:my_cd dirname(3) 函数设计格式:void my_cd(char *dirname)(4) 功能:改变当前目录到指定的名为dirname 的目录。
(5) 输入:dirname : 新的当前目录的目录名;(6) 输出:无(7) 函数需完成的工作:①调用my_open() 打开指定目录名的父目录文件,并调用do_read() 读入该父目录文件内容到内存中;②在父目录文件中检查新的当前目录名是否存在,如果存在则转③,否则返回,并显示出错信息;③调用my_close() 关闭①中打开的父目录文件;④调用my_close() 关闭原当前目录文件;⑤如果新的当前目录文件没有打开,则打开该目录文件;并将ptrcurdir 指向该打开文件表项;⑥设置当前目录为该目录。
5. 创建子目录函数my_mkdir()(1) 对应命令:my_mkdir(2)命令调用格式:my_ mkdir dirname(3)函数设计格式:void my_mkdir(char *dirname)(4)功能:在当前目录下创建名为dirname 的子目录。
(5) 输入:dirname : 新建目录的目录名。
(6) 输出:无。
(7) 函数需完成的工作:①调用do_read() 读入当前目录文件内容到内存,检查当前目录下新建目录文件是否重名,若重名则返回,并显示错误信息;②为新建子目录文件分配一个空闲打开文件表项,如果没有空闲表项则返回-1 ,并显示错误信息;③检查FAT是否有空闲的盘块,如有则为新建目录文件分配一个盘块,否则释放①中分配的打开文件表项,返回,并显示错误信息;④在当前目录中为新建目录文件寻找一个空闲的目录项或为其追加一个新的目录项;需修改当前目录文件的长度信息,并将当前目录文件的用户打开文件表项中的fcbstate 置为1;⑤准备好新建目录文件的FCB的内容,文件的属性为目录文件,以覆盖写方式调用do_write() 将其填写到对应的空目录项中;给根目录文件,在该磁盘上创建两个特殊的目录项:和“其内容除了文件名不同之外,其他⑥在新建目录文件所分配到的磁盘块中建立两个特殊的目录项到的磁盘块中;和".. ”目录项,方法⑦返回6. 删除子目录函数rmdir()-1。
(1) 对应命令: my_ rmdir(2) 命令调用格式: my_ rmdir dirname (1) (2) (3) 输入:函数设计格式: void my_rmdir(char *dirname) 功能:在当前目录下删除名为dirname 的子目录。
dirname : 欲删除目录的目录名。
(4) 输出:无。
(5) 函数需完成的工作:① 调用 do_read() 读入当前目录文件内容到内存,检查当前目录下欲删除目录文件是否存 在,若不存在则返回,并显示错误信息;② 检查欲删除目录文件是否为空 ( 除了“ . ”和外没有其他子目录和文件 ) ,可根据其 目录项中记录的文件长度来判断,若不为空则返回,并显示错误信息; ③ 检查该目录文件是否已经打开,若已打开则调用 ④ 回收该目录文件所占据的磁盘块,修改 FAT; ⑤ 从当前目录文件中清空该目录文件的目录项,且 do_write() 来实现;⑥ 修改当前目录文件的用户打开表项中的长度信息,并将表项中的 fcbstate 置为 1 ;⑦ 返回。
7. 显示目录函数 (1) 对应命令: my_ls() my_ls(2) (3) (4) 件信息)命令调用格式: my_ls函数设计格式: void my_ls(void)功能:显示当前目录的内容 (子目录和文。
(5) 输入:无 (6) 输出:无(7) 函数需完成的工作:① 调用 do_read() 读出当前目录文件内容到内存;② 将读出的目录文件的信息按照一定的格式显示到屏幕上; ③ 返回。
8. 创建文件函数 my_create()(1) 对应命令: my_create(3)函数设计格式: int my_create (char *filename)(5) 输入:filename : 新建文件的文件名,可能包含路径。
(6)建成功,返回该文件的文件描述符 ( 文件打开表中的数组下标 ) my_close() 关闭掉;free 字段置为 0:以覆盖写方式调用(2) 命令调用格式: my_create filename(4) 功能:创建名为 filename 的新文件。
输出:若创 ;否则返 回(7) 函数需完成的工作:①为新文件分配一个空闲打开文件表项,如果没有空闲表项则返回-1 ,并显示错误信息;②若新文件的父目录文件还没有打开,则调用my_open()打开;若打开失败,则释放①中-1。
为新建文件分配的空闲文件打开表项,返回-1 ,并显示错误信息;③调用do_read() 读出该父目录文件内容到内存,检查该目录下新文件是否重名,若重名则释放①中分配的打开文件表项,并调用my_close(关闭②中打开的目录文件;然后返回-1 ,并显示错误信息;④检查FAT是否有空闲的盘块,如有则为新文件分配一个盘块,否则释放①中分配的打开文件表项,并调用my_close()关闭②中打开的目录文件;返回-1,并显示错误信息;⑤在父目录中为新文件寻找一个空闲的目录项或为其追加一个新的目录项;需修改该目录文件的长度信息,并将该目录文件的用户打开文件表项中的fcbstate 置为1;⑥准备好新文件的FCB的内容,文件的属性为数据文件,长度为0,以覆盖写方式调用do_write() 将其填写到⑤中分配到的空目录项中;⑦为新文件填写①中分配到的空闲打开文件表项,fcbstate 字段值为0,读写指针值为0;⑧调用my_close() 关闭②中打开的父目录文件;⑨将新文件的打开文件表项序号作为其文件描述符返回。