收藏 分销(赏)

操作系统课程设计文件系统.doc

上传人:丰**** 文档编号:3583719 上传时间:2024-07-10 格式:DOC 页数:35 大小:207KB 下载积分:12 金币
下载 相关 举报
操作系统课程设计文件系统.doc_第1页
第1页 / 共35页
操作系统课程设计文件系统.doc_第2页
第2页 / 共35页


点击查看更多>>
资源描述
操作系统课程设计文件系统 35 2020年4月19日 文档仅供参考,不当之处,请联系改正。 学号 *************学院 课 程 设 计 课程名称 操作系统课程设计 题目 为LINUX 设计一个简单的二级文件系统 专 业 ********* 班 级 ******* 姓 名 ******** 成 绩 指导教师 *************** 1月17日 至 1月21日 课程设计任务书 设计题目:为LINUX 设计一个简单的二级文件系统 设计目的: 1、经过一个简单多用户文件系统的设计,加深理解文件系统的内部功能及内部实现。 2、提高学生的程序设计能力、 提高算法设计质量与程序设计素质 。 设计任务:(在规定的时间内完成下列任务) 为LINUX 设计一个简单的二级文件系统。要求做到以下几点: 1、能够实现下列几条命令(至少4条) Login 用户登录 Dir 列文件目录 Create 创立文件 Delete 删除文件 Open 打开文件 Close 关闭文件 Read 读文件 Write 写文件 2、列目录时要列出文件名、物理地址、保护码和文件长度。 3、源文件能够进行读写保护。 时间安排: 1月 17日 布置课程设计任务;分配题目后,查阅资料、 准备程序; 1月 18日~1月20 日上机调试程序、书写课程设计报告; 1月21 日上午提交课程设计报告及相关文档。 地点:学校机房(具体见现代教育中心大屏幕安排) 具体要求: 1、课程设计报告按统一通用格式书写,具体格式要求请在网络上查阅 2、每位学生应独立完成各自的任务且每天至少在设计室工作半天 指 导 教 师 签 名: 1月 7日 教研室主任(或责任教师)签名: 1月 7 日 目录 一. 项目概述 4 二. 课程设计设计题目 4 三. 开发语言及实现平台或实验环境 4 四. 设计目的 4 五. 设计内容 4 5.1. 任务 4 5.2. 主程序流程图 5 六. 程序设计 5 6.1. 设计思想 5 6.2. 设计要求 5 七. 设计原理 6 7.1. 外存管理 6 7.2. linux的EXT2文件系统 6 7.3. 用内存来模拟外存 6 7.4. 编码 7 八. 测试界面 15 九. 参考文献 17 十. 设计心得体会 17 十一. 设计过程中的疑问 18 十二. 指导教师评语 18 一.项目概述 Linux是一个性能稳定、功能强大、效率高的操作系统。它在功能特性方面与Unix系统相似,同时又具有多任务、多用户、多平台等若干特性。Linux的源代码是开放的,阅读Linux源代码,无疑是深入学习Linux的最好方法。   文件系统是Linux操作系统的重要组成部分,Linux文件具有强大的功能。文件系统中的文件是数据的集合,文件系统不但包含着文件中的数据而且还有文件系统的结构,所有Linux 用户和程序看到的文件、目录、软连接及文件保护信息等都存储在其中。 二. 课程设计设计题目 课程设计题目:Linux二级文件系统设计 三. 开发语言及实现平台或实验环境 开发语言:C++/VC++ 实现平台(环境):visual C++、window xp、VMware Workstation(虚拟机) V6.0.2、Red Hat Enterprise Linux os、office 四. 设计目的 (1)本实验的目的是经过一个简单多用户文件系统的设计,加深理解文件系统的内部功能和内部实现。 (2)结合数据结构、程序设计、计算机原理等课程的知识,设计一个二级文件系统,进一步理解操作系统。 (3)经过分对实际问题的分析、设计、编程实现,提高学生实际应用、编程的能力 五. 设计内容 5.1. 任务 为Linux系统设计一个简单的二级文件系统。要求做到以下几点: 1.能够实现下列几条命令: login 用户登录 dir 列目录 create 创立文件 delete 删除文件 open 打开文件 close 关闭文件 read 读文件 write 写文件 cd 进出目录 2.列目录时要列出文件名,物理地址,保护码和文件长度 3.源文件能够进行读写保护 5.2. 主程序流程图 结束 初始化文件目录表 初始化已打开文件表 输入用户名 主文件目录中又该用户? 输入文件操作命令 分析命令 建立子程序 打开子程序 关闭子程序 读子程序 写子程序 删除子程序 开始 无 此用 户 名 否 是 create open close read write delete 图1 主程序流程图 六. 程序设计 6.1. 设计思想 本文件系统采用两级目录,其中第一级对应于用户账号,第二级对应于用户帐号下的文件。另外,为了简便文件系统未考虑文件共享,文件系统安全以及管道文件与设备文件等特殊内容。 首先应确定文件系统的数据结构:主目录、子目录及活动文件等。主目录和子目录都以文件的形式存放于磁盘,这样便于查找和修改。 用户创立的文件,能够编号存储于磁盘上。如:file0,file1,file2…并以编号作为物理地址,在目录中进行登记。 6.2. 设计要求 理解Linux的文件系统的组织;掌握常见的数据结构;系统采用两级目录,其中第一级对应于用户账号,第二级对应于用户帐号下的文件;使用文件来模拟外存,进行数据结构设计和操作算法的设计,实现一个文件系统并实现基本的文件操作(为了简便文件系统,不考虑文件共享,文件系统安全以及管道文件与设备文件等特殊内容)。要求: 1、 对程序的每一部分要有详细的设计分析说明 2、 程序执行的每个步骤要有具体的提示内容或输出 3、 源代码格式规范,注释不少于三分之一 4、 设计合适的测试用例,对得到的运行结果要有分析, 5、 设计中遇到的问题,设计的心得体会 6、 提交完整程序代码、课程设计报告及相关文档 七. 设计原理 7.1. 外存管理 文件系统是一个含有大量的文件及其属性,对文件进行操作、管理的软件,以及向用户提供使用文件的接口的一个集合。在逻辑上它的层次结构是这样的: 文件系统接口 对对象的操作和管理的软件集合 逻辑文件系统 基本I/O管理程序(文件组织模块) 基本文件系统(物理I/O层) I/O控制层(设备驱动程序) 对象及其属性说明 作为产品的操作系统有各自的文件系统。比如MS的WINDOWS系列使用的是FAT16、FAT32或NTFS的文件系统、LINUX使用的是EXT2、EXT3文件系统等等。 7.2. linux的EXT2文件系统 linux使用一个叫虚拟文件系统的技术从而能够支持多达几十种的不同文件系统,而EXT2是linux自己的文件系统。它有几个重要的数据结构,一个是超级块,用来描述目录和文件在磁盘上的物理位置、文件大小和结构等信息。inode也是一个重要的数据结构。文件系统中的每个目录和文件均由一个inode描述。它包含:文件模式(类型和存取权限)、数据块位置等信息。如果希望详细学习EXT2文件系统能够参看linux内核代码include/linux/ext2_fs.h、include/linux/ext2_fs_sb.h等文件。 一个文件系统除了重要的数据结构之外,还必须为用户提供有效的接口操作。比如EXT2提供的OPEN/CLOSE接口操作。 7.3. 用内存来模拟外存 真正的文件系统对外存进行管理,涉及到许多硬件、设备管理方面的底层技术,一方面这些技术不属于操作系统核心内容,一方面过多的内容不免造成实验者顾此失彼,因此这里推荐一种使用内存来模拟外存的方式,能够跳过这些硬件技术而直接把精力放在数据结构设计和操作算法设计上面。 假定pInode是一个指向inode结构的指针,而且它已经放入的需要放入的数值了,现在需要将其写入到特定位置。可用如下代码: …… fd=fopen(“filesystem”,”w+b”); //fd是FILE指针类型,w便是写方式,b表示二进制 fseek(fd, specific_area,SEEK_SET);// fd是文件指针;specific_area为整形, // 为需要入pInode的位置 fwrite(pInode,1,sizeof(inode),fd); // 写入pInode信息 7.4. 编码 #include<stdio.h> #include<string.h> #include<stdlib.h> #define DIR_LENGTH 1024 /*路径最长可达100字节*/ #define MAX_WRITE 1024*128 /*写入文字可达128k字节*/ #define MEM_D_SIZE 1024*1024 /*1M磁盘空间*/ #define DISKSIZE 1024 /*磁盘块的大小 1K*/ #define MSD 5 /*最大子目录数 5 */ #define DISK_NUM MEM_D_SIZE/DISKSIZE /*磁盘块数目 1024=1M/1K*/ #define FATSIZE DISK_NUM*sizeof(struct fatitem) /*FAT表大小 */ #define MOFN 5 /*最大文件打开数 5 (即除根以外最大深度为5)*/ #define ROOT_DISK_NO FATSIZE/DISKSIZE+1 /*根目录起始盘快号 9*/ #define ROOT_DISK_SIZE sizeof(struct direct)/*根目录大小 196*/ /*---------------FAT表项结构-----------------------*/ struct fatitem /* size 8*/ { int item; /*存放文件下一个磁盘的指针*/ char em_disk; /*磁盘块是否空闲标志位 0 空闲*/ }; /*-------------------目录项结构------------------------*/ struct direct { /*-----文件控制快信息-----*/ struct FCB { char name[9]; /*文件/目录名 8位*/ char property; /*属性 1位目录 0位普通文件*/ int size; /*文件/目录字节数、盘块数)*/ int firstdisk; /*文件/目录 起始盘块号*/ int next; /*子目录起始盘块号*/ int sign; /*1是根目录 0不是根目录*/ }directitem[MSD+2]; }; /*------------------文件打开表项结构--------------------------*/ struct opentable { struct openttableitem { char name[9]; /*文件名*/ int firstdisk; /*起始盘块号*/ int size; /*文件的大小*/ }openitem[MOFN]; int cur_size; /*当前打文件的数目*/ }; /*-------------------------------------------------------------------*/ struct fatitem *fat; /*FAT表*/ struct direct *root; /*根目录*/ struct direct *cur_dir; /*当前目录*/ struct opentable u_opentable; /*文件打开表*/ int fd=-1; /*文件打开表的序号*/ char *bufferdir; /*记录当前路径的名称*/ char *fdisk; /*虚拟磁盘起始地址*/ int create(char *name); int open(char *name); int close(char *name); int write(int fd,char *buf,int len); int read(int fd,char *buf); int del(char *name); int mkdir(char *name); int rmdir(char *name); void dir(); int cd(char *name); /*-----------创立文件---------------------------------*/ int create(char *name) { int i,j; if(strlen(name)>8) /*文件名大于 8位*/ return(-1); for(j=2;j<MSD+2;j++) /*检查创立文件是否与已存在的文件重名*/ { if(!strcmp(cur_dir->directitem[j].name,name)) break; } if(j<MSD+2) /*文件已经存在*/ return(-4); for(i=2;i<MSD+2;i++) /*找到第一个空闲子目录*/ { if(cur_dir->directitem[i].firstdisk==-1) break; } if(i>=MSD+2) /*无空目录项*/ return(-2); if(u_opentable.cur_size>=MOFN) /*打开文件太多*/ return(-3); for(j=ROOT_DISK_NO+1;j<DISK_NUM;j++) /*找到空闲盘块 j 后退出*/ { if(fat[j].em_disk=='0') break; } if(j>=DISK_NUM) return(-5); fat[j].em_disk = '1'; /*将空闲块置为已经分配*/ /*-----------填写目录项-----------------*/ strcpy(cur_dir->directitem[i].name,name); cur_dir->directitem[i].firstdisk = j; cur_dir->directitem[i].size = 0; cur_dir->directitem[i].next = j; cur_dir->directitem[i].property = '0'; /*---------------------------------*/ fd = open(name); return 0; /*---------打开文件---------------------------*/ int open(char *name) { int i, j; for(i=2;i<MSD+2;i++) /*文件是否存在*/ { if(!strcmp(cur_dir->directitem[i].name,name)) break; } if(i>=MSD+2) return(-1); /*--------是文件还是目录-----------------------*/ if(cur_dir->directitem[i].property=='1') return(-4); /*--------文件是否打开-----------------------*/ for(j=0;j<MOFN;j++) { if(!strcmp(u_opentable.openitem[j].name,name)) break; } if(j<MOFN) /*文件已经打开*/ return(-2); if(u_opentable.cur_size>=MOFN) /*文件打开太多*/ return(-3); /*--------查找一个空闲用户打开表项-----------------------*/ for(j=0;j<MOFN;j++) { if(u_opentable.openitem[j].firstdisk==-1) break; } /*--------------填写表项的相关信息------------------------*/ u_opentable.openitem[j].firstdisk = cur_dir->directitem[i].firstdisk; strcpy(u_opentable.openitem[j].name,name); u_opentable.openitem[j].size = cur_dir->directitem[i].size; u_opentable.cur_size++; /*----------返回用户打开表表项的序号--------------------------*/ return(j); } /*-----------关闭文件------------------------*/ int close(char *name) { int i; for(i=0;i<MOFN;i++) { if(!strcmp(u_opentable.openitem[i].name,name)) break; } if(i>=MOFN) return(-1); /*----清空该文件的用户打开表项的内容---------------------*/ strcpy(u_opentable.openitem[i].name,""); u_opentable.openitem[i].firstdisk = -1; u_opentable.openitem[i].size = 0; u_opentable.cur_size--; return 0; } /*---------写文件---------------------------*/ int write(int fd, char *buf, int len) { char *first; int item, i, j, k; int ilen1, ilen2, modlen, temp; /*---用 $ 字符作为空格 # 字符作为换行符------------------*/ char Space = 32; char Endter= '\n'; for(i=0;i<len;i++) { if(buf[i] == '$') buf[i] = Space; else if(buf[i] == '#') buf[i] = Endter; } /*----读取用户打开表对应表项第一个盘块号----------*/ item = u_opentable.openitem[fd].firstdisk; /*--找到当前目录所对应表项的序号--------------*/ for(i=2;i<MSD+2;i++) { if(cur_dir->directitem[i].firstdisk==item) break; } temp = i; /*-存放当前目录项的下标-*/ /*------找到的item 是该文件的最后一块磁盘块-------------------*/ while(fat[item].item!=-1) { item =fat[item].item; /*-查找该文件的下一盘块--*/ } /*-----计算出该文件的最末地址-------*/ first = fdisk+item*DISKSIZE+u_opentable.openitem[fd].size%DISKSIZE; /*-----如果最后磁盘块剩余的大小大于要写入的文件的大小-------*/ if(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE>len) { strcpy(first,buf); u_opentable.openitem[fd].size = u_opentable.openitem[fd].size+len; cur_dir->directitem[temp].size = cur_dir->directitem[temp].size+len; } else { for(i=0;i<(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE);i++) {/*写一部分内容到最后一块磁盘块的剩余空间(字节)*/ first[i] = buf [i]; } /*计算分配完最后一块磁盘的剩余空间(字节) 还剩下多少字节未存储*/ ilen1 = len-(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE); ilen2 = ilen1/DISKSIZE; modlen = ilen1%DISKSIZE; if(modlen>0) ilen2 = ilen2+1; /*--还需要多少块磁盘块-*/ for(j=0;j<ilen2;j++) { for(i=ROOT_DISK_NO+1;i<DISK_NUM;i++)/*寻找空闲磁盘块*/ { if(fat[i].em_disk=='0') break; } if(i>=DISK_NUM) /*--如果磁盘块已经分配完了-*/ return(-1); first = fdisk+i*DISKSIZE; /*--找到的那块空闲磁盘块的起始地址-*/ if(j==ilen2-1) /*--如果是最后要分配的一块-*/ { for(k=0;k<len-(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE)-j*DISKSIZE;k++) first[k] = buf[k]; } else/*-如果不是要最后分配的一块--*/ { for(k=0;k<DISKSIZE;k++) first[k] =buf[k]; } fat[item].item = i; /*--找到一块后将它的序号存放在上一块的指针中-*/ fat[i].em_disk = '1'; /*--置找到的磁盘快的空闲标志位为已分配-*/ fat[i].item = -1; /*--它的指针为 -1 (即没有下一块)-*/ } /*--修改长度-*/ u_opentable.openitem[fd].size = u_opentable.openitem[fd].size+len; cur_dir->directitem[temp].size = cur_dir->directitem[temp].size+len; } return 0; } /*----------读文件--------------------*/ int read(int fd, char *buf) { int len = u_opentable.openitem[fd].size; char *first; int i, j, item; int ilen1, modlen; item = u_opentable.openitem[fd].firstdisk; ilen1 = len/DISKSIZE; modlen = len%DISKSIZE; if(modlen!=0) ilen1 = ilen1+1; /*--计算文件所占磁盘的块数-*/ first = fdisk+item*DISKSIZE; /*--计算文件的起始位置-*/ for(i=0;i<ilen1;i++) { if(i==ilen1-1) /*--如果在最后一个磁盘块-*/ { for(j=0;j<len-i*DISKSIZE;j++) buf[i*DISKSIZE+j] = first[j]; } else /*--不在最后一块磁盘块-*/ { for(j=0;j<len-i*DISKSIZE;j++) buf[i*DISKSIZE+j] = first[j]; item = fat[item].item; /*-查找下一盘块-*/ first = fdisk+item*DISKSIZE; } } return 0; } /*----删除文件--------------------*/ int del(char *name) { int i,cur_item,item,temp; for(i=2;i<MSD+2;i++) /*--查找要删除文件是否在当前目录中-*/ { if(!strcmp(cur_dir->directitem[i].name,name)) break; } cur_item = i; /*--用来保存目录项的序号,供释放目录中-*/ if(i>=MSD+2) /*--如果不在当前目录中-*/ return(-1); if(cur_dir->directitem[cur_item].property!='0') /*--如果删除的(不)是目录-*/ return(-3); for(i=0;i<MOFN;i++) /*--如果文件打开,则不能删除,退出-*/ { if(!strcmp(u_opentable.openitem[i].name,name)) return(-2); } item = cur_dir->directitem[cur_item].firstdisk; while(item!=-1) /*--释放空间,将FAT表对应项进行修改-*/ { temp = fat[item].item; fat[item].item = -1; fat[item].em_disk = '0'; item = temp; } /*-----------------释放目录项-----------------------*/ cur_dir->directitem[cur_item].sign = 0; cur_dir->directitem[cur_item].firstdisk = -1; strcpy(u_opentable.openitem[cur_item].name,""); cur_dir->directitem[cur_item].next = -1; cur_dir->directitem[cur_item].property = '0'; cur_dir->directitem[cur_item].size = 0; return 0; } /*---------创立子目录---------------------*/ int mkdir(char *name) { int i,j; struct direct *cur_mkdir; if(!strcmp(name,".")) return(-4); if(!strcmp(name,"..")) return(-4); if(strlen(name)>8) /*-如果目录名长度大于 8位-*/ return(-1); for(i=2;i<MSD+2;i++) /*-如果有空闲目录项退出-*/ { if(cur_dir->directitem[i].firstdisk==-1) break; } if(i>=MSD+2) /*-目录/文件 已满-*/ return(-2); for(j=2;j<MSD+2;j++) /*-判断是否有重名-*/ { if(!strcmp(cur_dir->directitem[j].name,name)) break; } if(j<MSD+2) /*-如果有重名-*/ return(-3); for(j=ROOT_DISK_NO+1;j<DISK_NUM;j++) /*-找到空闲磁盘块 j 后退出-*/ { if(fat[j].em_disk=='0') break; } if(j>=DISK_NUM) return(-5); fat[j].em_disk='1'; /*-将该空闲块设置为已分配-*/ /*-------------填写目录项----------*/ strcpy(cur_dir->directitem[i].name,name); cur_dir->directitem[i].firstdisk=j; cur_dir->directitem[i].size=ROOT_DISK_SIZE; cur_dir->directitem[i].next=j; cur_dir->directitem[i].property='1'; /*-所创目录在虚拟磁盘上的地址(内存物理地址)-*/ cur_mkdir=(struct direct *)(fdisk+cur_dir->directitem[i].firstdisk*DISKSIZE); /*-初始化目录-*/ /*-指向当前目录的目录项-*/ cur_mkdir->directitem[0].sign=0; cur_mkdir->directitem[0].firstdisk=cur_dir->directitem[i].firstdisk; strcpy(cur_mkdir->directitem[0].name,"."); cur_mkdir->directitem[0].next=cur_mkdir->directitem[0].firstdisk; cur_mkdir->directitem[0].property='1'; cur_mkdir->directitem[0].size=ROOT_DISK_SIZE; /*-指向上一级目录的目录项-*/ cur_mkdir->directitem[1].sign=cur_dir->directitem[0].sign; cur_mkdir->directitem[1].firstdisk=cur_dir->directitem[0].firstdisk; strcpy(cur_mkdir->directitem[1].name,".."); cur_mkdir->directitem[1].next=cur_mkdir->directitem[1].firstdisk; cur_mkdir->directitem[1].property='1'; cur_mkdir->directitem[1].size=ROOT_DISK_SIZE; for(i=2;i<MSD+2;i++) /*-子目录都初始化为空-*/ { cur_mkdir->directitem[i].sign=0; cur_mkdir->direct
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 学术论文 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服