logo资料库

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

第1页 / 共21页
第2页 / 共21页
第3页 / 共21页
第4页 / 共21页
第5页 / 共21页
第6页 / 共21页
第7页 / 共21页
第8页 / 共21页
资料共21页,剩余部分请下载后查看
操作系统课程设计之三 设计任务:模拟 OS 文件系统 在任一 OS(Window 或者 Dos;也可以是在 Linux 下,但要求能将结果演示给老 师看)下,建立一个大文件,把它假象成一张盘,在其中实现一个简单的模拟 OS 文件系统。 1、在现有机器硬盘上开辟 10M(共 10000 个盘块,每盘块大小为 1k)的硬盘空间 (生成一个 10M 的用户文件 SDisk.dat 即可),作为设定的硬盘空间。 2、编写一管理程序 SDisk,对此空间进行管理,以模拟 OS 文件系统,要求: ⑴、盘块大小 1k ⑵、空闲盘块的管理:采用位示图法 ⑶、文件空间管理:采用 FAT(文件分配表),每个盘块号占 2 个字节 ⑷、目录项管理: ①、每个目录项占用 32 字节,其中前 8 个字节(0-7)为文件名,之后跟 3 个字节 (8-10)的扩展名,26-27 字节,存放文件的第一个盘块号,最后四个字节 (28-31),存放文件长度(如果目录项对应的是下一级子目录(文件),其文件 长度部分为 0) ②、目录按文件方式管理,每个目录仅用一个盘块(即 1k,最多装 32 个目录项) ③、第 0 个目录项为本目录,即“.”,第 0 个字节为“.”,即 0x2E,第 26-27 字 节指明本目录所在盘块。 ④、第 1 个目录项为父目录,即“..”,第 0,1 个字节为“..”即 0x2E,0x2E,第 26-27 字节指明父目录所在盘块。 ⑤、每个目录实际能放下文件或子目录 30 项。 ⑸、文件系统空间分配: ①、第 0 个盘块(1k)存放磁盘信息(可以设定为格式说明“FAT32”、盘块大小,盘块数等 内容) ②、第 1 个盘块起,至 125 盘块,共 125 个盘块(125k)存放 FAT 内容 ③、第 126、127(2 个)盘块,存放位示图 ④、从第 128 盘块至 10000 盘块,皆为数据(区)盘块,其逻辑编号从 0 开始,至
9872 号数据盘块,即第 0 数据盘块为 128 号盘块,第 1 数据盘块为 129 号盘块,… ⑤、第 0 数据盘块(即 128 号盘块),存放根目录(同样只用一个盘块作根目录), 由于第 0、1 目录项为“.”(本目录), “..”(父目录),因此根目录下同 样只能存放 30 个文件或目录,并且从第 2 个目录项开始。 ⑥、文件或子目录数据,放在第 1 数据盘块及以后的数据盘块中,由用户按需要使 用。 3、SDisk 管理程序的功能要求如下: ⑴、正常情况下,显示等待命令输入符号# ⑵、改变目录命令: #cd 目录名,改变当前工作目录,目录不存在时给出出错信息 #cd ..,返回上一级目录,如果是根目录,给出提示信息 ⑶、生成新目录 #md 目录名,创建新目录(需要更改 FAT 内容和位示图内容) ⑷、删除目录 #rd 目录名,删除目录,如果目录不存在时给出出错信息(需要更改 FAT 内容 和位示图内容) ⑸、显示目录 #dir,显示指定目录下或当前目录下的信息,包括文件名、扩展名、物理地址 (文件或目录第一个盘块号)、文件长度、子目录 ⑹、创建新文件 #CreateFile 文件名.扩展名 文件长度,根据文件名.扩展名,创建一个目录项 (fcb),根据文件长度和位示图中空闲盘块情况,分配足够多的连续盘块,给新文 件(需要更改 FAT 内容和位示图内容)。 ⑺、删除文件 #DelFile 文件名.扩展名,在文件所在的目录项中,将第一个字节变为 0xE5, 并同时修改 FAT 内容和位示图内容;如果文件不存在,给出出错信息 ⑻、文件拷贝 #CopyFile 老文件,新文件,为新文件创建一个目录项,并将老文件内容复制到 新文件中,并同时修改 FAT 内容和位示图内容 ⑼、显示位示图内容 #ShowBitMP,将位示图内容(已有信息部分),显示在屏幕上(按十六进制)
⑽、显示 FAT 内容 #ShowFAT,将 FAT 内容(已有信息部分),显示在屏幕上(按十六进制) 4、程序的总体流程为: ⑴、输出提示符#,等待接受命令,分析键入的命令; ⑵、对合法的命令,执行相应的处理程序,否则输出错误信息,继续等待新命令 (1、请参考“03.FAT32文件系统简介.doc”中,有关文件系统的规定; 2、请参考WinHex中,目录所显示的信息进行编程) //关于 FAT 和 MAP 表的解释 //用 bitset 库,做 MAP 的是否判断,因为作业要求从数据块从 128 位开始,所以 bitset 的前 128 位被置为-1,同样 FAT 表也是,其次,MAP 表和 FAT 表同样是用数 组方式做保存,这样就略过了是对具体地址的操作,从数组的下标很容易的定位, 关于对 FAT 表和 MAP 表的用法 1. 当要用到数据块是,查询 MAP 表(因为只做比较查询即可),查询到的未用位置 置 1,然后在 FAT 表上进行相应记录,在本程序做出的规定是,当文件夹 FAT 表做-1,若是文件则按照 FAT 做对应的顺序记录,最后一块同样是-1 结束, 2. 回收的时候,是按照 FAT 表的首项,做顺序置 0,然后 MAP 也在相应位置置 0
#include #include #include #include #include /***********************************************************/ //AUTHOR:CHENLOG //ENVIROMENT:VC2008 WIN7 //DATE:2011-6-5 VERSION 1.0 /***********************************************************/ using namespace std; const int BLOCKNUM_SIZE=2; const int BLOCK_SIZE=1024; const int BLOCK_NUM=10001; const int DISK_SIZE=1024*1000*10; const int LIST_SIZE=32; const int MAP_SIZE=10001; const int FATNUM=125; const int FATLIST=512; const int DATABEG=128; //盘块号大小 //一个盘块大小数 //盘块数量 //磁盘大小 //目录项大小 //MAP 长度 //FAT的盘块数 第块没有用 //每个盘口FAT的记录数 //数据项开始FAT号 struct FCB { char fname[8]; char exname[3]; short fnum; int length; //文件名 //扩展名 //首块号 //文件大小, 目录则文件大小为;
}; struct fatid{ short id[FATNUM*FATLIST]; //FAT 大小512个记录 一块 //当前FAT号 //当前目录块号初始化是+1 由于第个单元没有使用 //磁盘的首地址 //window文件保存地址 //window 文件地址 //当前路径 //输入指令 }*FAT; struct map{ bitset maplist; }*MAP; struct DIR { struct FCB list[LIST_SIZE+1]; }*filedir; int currentid=128; int currentdir=128; char *file; char *FilePath="myfat"; FILE *fp; string CURRENT="root\\"; char cmd[30]; char command[16]; /* *对文件存储器进行格式化 *创建根目录 * */ void findBit(struct map *MAP) { } void init(struct fatid *FAT) { int i,j; for(i=1;iDATABEG) FAT->id[i]=0; else FAT->id[i]=-1;
} } void format() { bool i; FAT=(struct fatid *)(file+BLOCK_SIZE); //当前FAT地址 MAP=(struct map *)(file+(FATNUM+1)*BLOCK_SIZE); init(FAT); //初始化位示图 FAT->id[0]=9872; filedir=(struct DIR *)(file+(FATNUM+1+2)*BLOCK_SIZE); //当前目录指针地址 FAT->id[128]=-1; FAT->id[0]=9872-1; strcpy(filedir->list[0].fname,"."); strcpy(filedir->list[0].exname,"dir"); filedir->list[0].fnum=currentdir; filedir->list[0].length=0; strcpy(filedir->list[1].fname,".."); strcpy(filedir->list[1].exname,"dir"); filedir->list[1].fnum=currentdir; filedir->list[1].length=0; fp=fopen(FilePath,"w+"); fwrite(file,sizeof(char),DISK_SIZE,fp); fclose(fp); printf("初始化已经完成,现在可以进行操作了!\n\n"); } /* *创建子目录 */ int mkdir(char *str) { int i,j; int blockid; //将要创建的FAT号
int blockdir; int listnum; //将要创建的目录块号 //目录块内编号 //当前目录指针 struct fatid *flagid; struct DIR *dir; struct map *MAP; struct fatid *FAT; if(strcmp(str,"")==0) { printf("目录名称不能为空\n"); return 0; } dir=(struct DIR *)(file+(currentdir)*BLOCK_SIZE); MAP=(struct map *)(file+(FATNUM+1)*BLOCK_SIZE); FAT=(struct fatid *)(file+BLOCK_SIZE); //从128块数据块 实际上的块开始搜索 for(i=DATABEG+1;imaplist[i]==0) break; } if(i>BLOCK_NUM) { printf("内存不足\n"); return 0; } MAP->maplist[i]=1; //map 置即已用 dir=(struct DIR *)(file+(currentdir)*BLOCK_SIZE); for(i=2;ilist[i].fname,str)==0) { printf("目录下有同名文件夹\n"); return 0; } } for(i=2;ilist[i].fname,"")==0) //有空的目录块且无重名,第一版本的时候与上面 的循环放在一起,存在一个情况是前面的建立的目录删除后,直接被同名的覆盖了 break; if(i>LIST_SIZE) { printf("内存不足\n"); return 0;
} } flagid=(struct fatid *)(file+BLOCK_SIZE); //fat 首位地址 for(j=DATABEG+1;jid[j]==0) { blockdir=j; break; } } strcpy(dir->list[i].fname,str); dir->list[i].fnum=blockdir; strcpy(dir->list[i].exname,"dir"); dir->list[i].length=0; //为新目录项创建根目录 dir=(struct DIR *)(file+blockdir*BLOCK_SIZE); strcpy(dir->list[0].fname,"."); strcpy(dir->list[0].exname,"dir"); dir->list[0].fnum=blockdir; dir->list[0].length=0; strcpy(dir->list[1].fname,".."); strcpy(dir->list[1].exname,"dir"); dir->list[1].fnum=currentdir; dir->list[1].length=0; flagid->id[j]=-1; FAT->id[0]=FAT->id[0]-1; //修改FAT 目录尾部 printf("已经成功创建目录%s \n",str); return 0; } /* *显示目录 */ int listshow() { int i,sumfile,sumdir,fl[100],dr[100];//fl 为文件的号数,dr为目录的号数 sumfile=sumdir=0; struct DIR *dir; struct fatid *FAT; dir=(struct DIR *)(file+currentdir*BLOCK_SIZE); for(i=0;ilist[i].length==0&&(strcmp(dir->list[i].fname,"")!=0)&&(dir->list[i].fnum!=0))
分享到:
收藏