《操作系统课程设计简单文件系统的实现361.pdf》由会员分享,可在线阅读,更多相关《操作系统课程设计简单文件系统的实现361.pdf(33页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、.操作系统课程设计报告 小组编号:小组成员:一、课程设计概述:1、题目:简单文件系统的实现 2、实现内容(1)在内存中开辟一个虚拟磁盘空间作为文件存储分区,在其上实现一个简单的基于多级目录的单用户单任务系统中的文件系统。在退出该文件系统的使用时,应将该虚拟文件系统以一个 Windows 文件的方式保存到磁盘上,以便下次可以再将它恢复到内存的虚拟磁盘空间中。(2)文件存储空间的分配可采用显式链接分配或其他的办法。(3)空闲磁盘空间的管理可选择位示图或其他的办法。如果采用位示图来管理文件存储空间,并采用显式链接分配方式,那么可以将位示图合并到 FAT 中。(4)文件目录结构采用多级目录结构。为了简
2、单起见,可以不使用索引结点,其中的每个目录项应包含文件名、物理地址、长度等信息,还可以通过目录项实现对文件的读和写的保护。(5)要求提供以下操作命令:my_format:对文件存储器进行格式化,即按照文件系统的结构对虚拟磁盘空间进行布局,并在其上创建根目录以及用于管理文件存储空间等的数据结构。my_mkdir:用于创建子目录。my_rmdir:用于删除子目录。my_ls:用于显示目录中的内容。my_cd:用于更改当前目录。my_create:用于创建文件。my_open:用于打开文件。my_close:用于关闭文件。my_write:用于写文件。my_read:用于读文件。my_rm:用于删除
3、文件。my_exitsys:用于退出文件系统。二、设计思路(主要算法描述、程序流程图等):1系统主函数 main()(1)对应命令:无(2)命令调用格式:无(3)函数设计格式:void main()(4)功能:系统主函数(5)输入:无(6)输出:无(7)函数需完成的工作:对前面定义的全局变量进行初始化;调用 startsys()进入文件系统;.列出文件系统提供的各项功能及命令调用格式;显示命令行提示符,等待用户输入命令;将用户输入的命令保存到一个 buf 中;对 buf 中的内容进行命令解析,并调用相应的函数执行用户键入的命令;如果命令不是“my_exitsys”,则命令执行完毕后转。2.进入
4、文件系统函数 startsys()(1)对应命令:无(2)命令调用格式:无(3)函数设计格式:void startsys()(4)功能:由 main()函数调用,进入并初始化我们所建立的文件系统,以供用户使用。(5)输入:无 (6)输出:无。(7)函数需完成的工作:申请虚拟磁盘空间;使用 c 语言的库函数 fopen()打开 myfsys 文件:若文件存在,则转;若文件不存在,则创建之,转 使用 c 语言的库函数 fread()读入 myfsys 文件内容到用户空间中的一个缓冲区中,并判断其开始的 8 个字节内容是否为“”(文件系统魔数),如果是,则转;否则转;将上述缓冲区中的内容复制到内存中
5、的虚拟磁盘空间中;转 在屏幕上显示“myfsys 文件系统不存在,现在开始创建文件系统”信息,并调用my_format()对中申请到的虚拟磁盘空间进行格式化操作。转;将虚拟磁盘中的内容保存到 myfsys 文件中;转 使用 c 语言的库函数 fclose()关闭 myfsys 文件;初始化用户打开文件表,将表项 0 分配给根目录文件使用,并填写根目录文件的相关信息,由于根目录没有上级目录,所以表项中的 dirno 和 diroff 分别置为 5(根目录所在起始块号)和 0;并将 ptrcurdir 指针指向该用户打开文件表项。将当前目录设置为根目录。3磁盘格式化函数 my_format()(1
6、)对应命令:my_format(2)命令调用格式:my_format(3)函数设计格式:void my_format()(4)功能:对虚拟磁盘进行格式化,布局虚拟磁盘,建立根目录文件(或根目录区)。(5)输入:无 (6)输出:无。(7)函数需完成的工作:将虚拟磁盘第一个块作为引导块,开始的 8 个字节是文件系统的魔数,记为“”;在之后写入文件系统的描述信息,如 FAT 表大小及位置、根目录大小及位置、盘块大小、盘块数量、数据区开始位置等信息;在引导块后建立两张完全一样的 FAT 表,用于记录文件所占据的磁盘块及管理虚拟磁盘块的分配,每个 FAT 占据两个磁盘块;对于每个 FAT 中,前面 5
7、个块设置为已分配,后面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()
8、打开指定目录名的父目录文件,并调用 do_read()读入该父目录文件内容到内存中;在父目录文件中检查新的当前目录名是否存在,如果存在则转,否则返回,并显示出错信息;调用 my_close()关闭中打开的父目录文件;调用 my_close()关闭原当前目录文件;如果新的当前目录文件没有打开,则打开该目录文件;并将 ptrcurdir 指向该打开文件表项;设置当前目录为该目录。5创建子目录函数 my_mkdir()(1)对应命令:my_mkdir(2)命令调用格式:my_ mkdir dirname(3)函数设计格式:void my_mkdir(char*dirname)(4)功能:在当前目录下
9、创建名为 dirname 的子目录。(5)输入:dirname:新建目录的目录名。(6)输出:无。(7)函数需完成的工作:调用 do_read()读入当前目录文件内容到内存,检查当前目录下新建目录文件是否重名,若重名则返回,并显示错误信息;为新建子目录文件分配一个空闲打开文件表项,如果没有空闲表项则返回-1,并显示错误信息;检查 FAT 是否有空闲的盘块,如有则为新建目录文件分配一个盘块,否则释放中分配的打开文件表项,返回,并显示错误信息;在当前目录中为新建目录文件寻找一个空闲的目录项或为其追加一个新的目录项;需修改当前目录文件的长度信息,并将当前目录文件的用户打开文件表项中的 fcbstat
10、e 置为 1;准备好新建目录文件的 FCB 的内容,文件的属性为目录文件,以覆盖写方式调用do_write()将其填写到对应的空目录项中;在新建目录文件所分配到的磁盘块中建立两个特殊的目录项“.”和“.”目录项,方法是:首先在用户空间中准备好内容,然后以截断写或者覆盖写方式调用 do_write()将其写到中分配到的磁盘块中;返回。6删除子目录函数 rmdir()(1)对应命令:my_ rmdir(2)命令调用格式:my_ rmdir dirname.(1)函数设计格式:void my_rmdir(char*dirname)(2)功能:在当前目录下删除名为 dirname 的子目录。(3)输入
11、:dirname:欲删除目录的目录名。(4)输出:无。(5)函数需完成的工作:调用 do_read()读入当前目录文件内容到内存,检查当前目录下欲删除目录文件是否存在,若不存在则返回,并显示错误信息;检查欲删除目录文件是否为空(除了“.”和“.”外没有其他子目录和文件),可根据其目录项中记录的文件长度来判断,若不为空则返回,并显示错误信息;检查该目录文件是否已经打开,若已打开则调用 my_close()关闭掉;回收该目录文件所占据的磁盘块,修改 FAT;从当前目录文件中清空该目录文件的目录项,且 free 字段置为 0:以覆盖写方式调用do_write()来实现;修改当前目录文件的用户打开表项
12、中的长度信息,并将表项中的 fcbstate 置为 1;返回。7显示目录函数 my_ls()(1)对应命令:my_ls(2)命令调用格式:my_ls(3)函数设计格式:void my_ls(void)(4)功能:显示当前目录的内容(子目录和文件信息)。(5)输入:无 (6)输出:无(7)函数需完成的工作:调用 do_read()读出当前目录文件内容到内存;将读出的目录文件的信息按照一定的格式显示到屏幕上;返回。8创建文件函数 my_create()(1)对应命令:my_create(2)命令调用格式:my_create (3)函数设计格式:int my_create(char*)(4)功能:创
13、建名为的新文件。(5)输入:新建文件的文件名,可能包含路径。(6)输出:若创建成功,返回该文件的文件描述符(文件打开表中的数组下标);否则返回-1。(7)函数需完成的工作:为新文件分配一个空闲打开文件表项,如果没有空闲表项则返回-1,并显示错误信息;若新文件的父目录文件还没有打开,则调用 my_open()打开;若打开失败,则释放中为新建文件分配的空闲文件打开表项,返回-1,并显示错误信息;调用 do_read()读出该父目录文件内容到内存,检查该目录下新文件是否重名,若重名则释放中分配的打开文件表项,并调用 my_close()关闭中打开的目录文件;然后返回-1,并显示错误信息;检查 FAT
14、 是否有空闲的盘块,如有则为新文件分配一个盘块,否则释放中分配的打开.文件表项,并调用 my_close()关闭中打开的目录文件;返回-1,并显示错误信息;在父目录中为新文件寻找一个空闲的目录项或为其追加一个新的目录项;需修改该目录文件的长度信息,并将该目录文件的用户打开文件表项中的 fcbstate 置为 1;准备好新文件的 FCB 的内容,文件的属性为数据文件,长度为 0,以覆盖写方式调用do_write()将其填写到中分配到的空目录项中;为新文件填写中分配到的空闲打开文件表项,fcbstate 字段值为 0,读写指针值为 0;调用 my_close()关闭中打开的父目录文件;将新文件的打
15、开文件表项序号作为其文件描述符返回。9删除文件函数 my_rm()(1)对应命令:my_rm(2)命令调用格式:my_rm (3)函数设计格式:void my_rm(char*)(4)功能:删除名为的文件。(5)输入:欲删除文件的文件名,可能还包含路径。(6)输出:无。(7)函数需完成的工作:若欲删除文件的父目录文件还没有打开,则调用 my_open()打开;若打开失败,则返回,并显示错误信息;调用 do_read()读出该父目录文件内容到内存,检查该目录下欲删除文件是否存在,若不存在则返回,并显示错误信息;检查该文件是否已经打开,若已打开则关闭掉;回收该文件所占据的磁盘块,修改 FAT;从文
16、件的父目录文件中清空该文件的目录项,且 free 字段置为 0:以覆盖写方式调用do_write()来实现;修改该父目录文件的用户打开文件表项中的长度信息,并将该表项中的 fcbstate 置为 1;返回。10打开文件函数 my_open()(1)对应命令:my_open(2)命令调用格式:my_open (3)函数设计格式:int my_open(char*)(4)功能:打开当前目录下名为的文件。(5)输入:欲打开文件的文件名 (6)输出:若打开成功,返回该文件的描述符(在用户打开文件表中表项序号);否则返回-1。(7)函数需完成的工作:检查该文件是否已经打开,若已打开则返回-1,并显示错误
17、信息;调用 do_read()读出父目录文件的内容到内存,检查该目录下欲打开文件是否存在,若不存在则返回-1,并显示错误信息;检查用户打开文件表中是否有空表项,若有则为欲打开文件分配一个空表项,若没有则返回-1,并显示错误信息;为该文件填写空白用户打开文件表表项内容,读写指针置为 0;将该文件所分配到的空白用户打开文件表表项序号(数组下标)作为文件描述符 fd 返回。.11关闭文件函数 my_close()(1)对应命令:my_close(2)命令调用格式:my_close fd(3)函数设计格式:void my_close(int fd)(4)功能:关闭前面由 my_open()打开的文件描
18、述符为 fd 的文件。(5)输入:fd:文件描述符。(6)输出:无。(7)函数需完成的工作:检查 fd 的有效性(fd 不能超出用户打开文件表所在数组的最大下标),如果无效则返回-1;检查用户打开文件表表项中的 fcbstate 字段的值,如果为 1 则需要将该文件的 FCB 的内容保存到虚拟磁盘上该文件的目录项中,方法是:打开该文件的父目录文件,以覆盖写方式调用 do_write()将欲关闭文件的 FCB 写入父目录文件的相应盘块中;回收该文件占据的用户打开文件表表项(进行清空操作),并将 topenfile 字段置为 0;返回。12写文件函数 my_write()(1)对应命令:my_wr
19、ite(2)命令调用格式:my_write fd(3)函数设计格式:int my_write(int fd)(4)功能:将用户通过键盘输入的内容写到 fd 所指定的文件中。磁盘文件的读写操作都必须以完整的数据块为单位进行,在写操作时,先将数据写在缓冲区中,缓冲区的大小与磁盘块的大小相同,然后再将缓冲区中的数据一次性写到磁盘块中;读出时先将一个磁盘块中的内容读到缓冲区中,然后再传送到用户区。本实例为了简便起见,没有设置缓冲区管理,只是在读写文件时由用户使用 malloc()申请一块空间作为缓冲区,读写操作结束后使用free()释放掉。写操作常有三种方式:截断写、覆盖写和追加写。截断写是放弃原来文
20、件的内容,重新写文件;覆盖写是修改文件在当前读写指针所指的位置开始的部分内容;追加写是在原文件的最后添加新的内容。在本实例中,输入写文件命令后,系统会出现提示让用户选择其中的一种写方式,并将随后键盘输入的内容按照所选的方式写到文件中,键盘输入内容通过CTR+Z键(或其他设定的键)结束。(5)输入:fd:open()函数的返回值,文件的描述符;(6)输出:实际写入的字节数。(7)函数需完成的工作:检查 fd 的有效性(fd 不能超出用户打开文件表所在数组的最大下标),如果无效则返回-1,并显示出错信息;提示并等待用户输入写方式:(1:截断写;2:覆盖写;3:追加写)如果用户要求的写方式是截断写,
21、则释放文件除第一块外的其他磁盘空间内容(查找并修改 FAT 表),将内存用户打开文件表项中文件长度修改为 0,将读写指针置为 0 并转;如果用户要求的写方式是追加写,则修改文件的当前读写指针位置到文件的末尾,并转;如果写方式是覆盖写,则直接转;提示用户:整个输入内容通过 CTR+Z 键(或其他设定的键)结束;用户可分多次输入写入内容,每次用回车结束;.等待用户从键盘输入文件内容,并将用户的本次输入内容保存到一临时变量 text中,要求每次输入以回车结束,全部结束用 CTR+Z 键(或其他设定的键);调用 do_write()函数将通过键盘键入的内容写到文件中。如果 do_write()函数的返
22、回值为非负值,则将实际写入字节数增加 do_write()函数返回值,否则显示出错信息,并转;如果 text中最后一个字符不是结束字符 CTR+Z,则转继续进行写操作;否则转;如果当前读写指针位置大于用户打开文件表项中的文件长度,则修改打开文件表项中的文件长度信息,并将 fcbstate 置 1;返回实际写入的字节数。13实际写文件函数 do_write()(1)对应命令:无(2)命令调用格式:无(3)函数设计格式:int my_write(int fd,char*text,int len,char wstyle)(4)功能:被写文件函数 my_write()调用,用来将键盘输入的内容写到相应
23、的文件中去。(5)输入:fd:open()函数的返回值,文件的描述符;text:指向要写入的内容的指针;len:本次要求写入字节数 wstyle:写方式(6)输出:实际写入的字节数。(7)函数需完成的工作:用 malloc()申请 1024B 的内存空间作为读写磁盘的缓冲区 buf,申请失败则返回-1,并显示出错信息;将读写指针转化为逻辑块块号和块内偏移off,并利用打开文件表表项中的首块号及FAT表的相关内容将逻辑块块号转换成对应的磁盘块块号 blkno;如果找不到对应的磁盘块,则需要检索 FAT 为该逻辑块分配一新的磁盘块,并将对应的磁盘块块号 blkno 登记到 FAT 中,若分配失败,
24、则返回-1,并显示出错信息;如果是覆盖写,或者如果当前读写指针所对应的块内偏移 off 不等于 0,则将块号为 blkno的虚拟磁盘块全部 1024B 的内容读到缓冲区 buf 中;否则便用 ASCII 码 0 清空 buf;将 text 中未写入的内容暂存到缓冲区 buff 的第 off 字节开始的位置,直到缓冲区满,或者接收到结束字符 CTR+Z 为止;将本次写入字节数记录到 tmplen 中;将 buf 中 1024B 的内容写入到块号为 blkno 的虚拟磁盘块中;将当前读写指针修改为原来的值加上 tmplen;并将本次实际写入的字节数增加 tmplen;如果 tmplen 小于 le
25、n,则转继续写入;否则转;返回本次实际写入的字节数。14读文件函数 my_read()(1)对应命令:my_read(2)命令调用格式:my_read fd len(3)函数设计格式:int myread(int fd,int len)(4)功能:读出指定文件中从读写指针开始的长度为 len 的内容到用户空间中。(5)输入:fd:open()函数的返回值,文件的描述符;len:要从文件中读出的字节数。(6)输出:实际读出的字节数。.(7)函数需完成的工作:定义一个字符型数组 textlen,用来接收用户从文件中读出的文件内容;检查 fd 的有效性(fd 不能超出用户打开文件表所在数组的最大下标
26、),如果无效则返回-1,并显示出错信息;调用 do_read()将指定文件中的 len 字节内容读出到 text中;如果 do_read()的返回值为负,则显示出错信息;否则将 text中的内容显示到屏幕上;返回。15实际读文件函数 do_read()(1)对应命令:无(2)命令调用格式:无(3)函数设计格式:int do_read(int fd,int len,char*text)(4)功能:被 my_read()调用,读出指定文件中从读写指针开始的长度为 len 的内容到用户空间的 text 中。(5)输入:fd:open()函数的返回值,文件的描述符;len:要求从文件中读出的字节数。t
27、ext:指向存放读出数据的用户区地址(6)输出:实际读出的字节数。(7)函数需完成的工作:使用 malloc()申请 1024B 空间作为缓冲区 buf,申请失败则返回-1,并显示出错信息;将读写指针转化为逻辑块块号及块内偏移量 off,利用打开文件表表项中的首块号查找FAT 表,找到该逻辑块所在的磁盘块块号;将该磁盘块块号转化为虚拟磁盘上的内存位置;将该内存位置开始的 1024B(一个磁盘块)内容读入 buf 中;比较 buf 中从偏移量 off 开始的剩余字节数是否大于等于应读写的字节数 len,如果是,则将从 off 开始的 buf 中的 len 长度的内容读入到 text中;否则,将从
28、 off 开始的 buf 中的剩余内容读入到 text中;将读写指针增加中已读字节数,将应读写的字节数 len 减去中已读字节数,若 len大于 0,则转;否则转;使用 free()释放中申请的 buf。返回实际读出的字节数。16.退出文件系统函数 my_exitsys()(1)对应命令:my_exitsys(2)命令调用格式:my_ exitsys(1)函数设计格式:void my_exitsys()(2)功能:退出文件系统。(3)输入:无 (4)输出:无。(5)函数需完成的工作:使用 C 库函数 fopen()打开磁盘上的 myfsys 文件;将虚拟磁盘空间中的所有内容保存到磁盘上的 my
29、fsys 文件中;使用 c 语言的库函数 fclose()关闭 myfsys 文件;撤销用户打开文件表,释放其内存空间 释放虚拟磁盘空间。流程图 程序启动.是 否 等待用户命令输入 三、程序实现代码:#include#include#include#include 文 件 系统 是 否存在 加载文件系统 创建文件系统,并格式化 用户输入命令 my_ls my_create my_rm my_open my_exitsys.#define BLOCKSIZE 1024 /磁盘块大小#define SIZE 1024000 /虚拟磁盘空间大小#define END 65535 /FAT 中的文件结
30、束标志#define FREE 0 /FAT 中盘块空闲标志#define ROOTBLOCKNUM 2 /根目录区所占盘块数#define MAXOPEN /最多同时打开文件个数 t#define MAXTEXT 10000 /*文件控制块*/typedef struct FCB char 8;/文件名 char exname3;/文件扩展名 unsigned char attribute;/文件属性字段,值为 0 时表示目录文件,值为 1 时表示数据文件 unsigned short time;/文件创建时间 unsigned short date;/文件创建日期 unsigned sho
31、rt first;/文件起始盘块号 unsigned long length;/文件长度 char free;/表示目录项是否为空,若值为 0,表示空,值为 1,表示已分配 fcb;/*文件分配表*/typedef struct FAT unsigned short id;/磁盘块的状态(空闲的,最后的,下一个)fat;/*用户打开文件表*/typedef struct USEROPEN char 8;/文件名 char exname3;/文件扩展名 unsigned char attribute;/文件属性字段,值为 0 时表示目录文件,值为 1 时表示数据文件 unsigned short
32、 time;/文件创建时间 unsigned short date;/文件创建日期 unsigned short first;/文件起始盘块号 unsigned long length;/文件长度(对数据文件是字节数,对目录文件可以是目录项个数)char free;/表示目录项是否为空,若值为 0,表示空,值为 1,表示已分配 unsigned short dirno;/相应打开文件的目录项在父目录文件中的盘块号 int diroff;/相应打开文件的目录项在父目录文件的 dirno 盘块中的目录项序号 char dir80;/相应打开文件所在的路径名,这样方便快速检查出指定文件是否已经打开.
33、int father;/父目录在打开文件表项的位置 int count;/读写指针在文件中的位置,文件的总字符数 char fcbstate;/是否修改了文件的 FCB 的内容,如果修改了置为 1,否则为 0 char topenfile;/表示该用户打开表项是否为空,若值为 0,表示为空,否则表示已被某打开文件占据 useropen;/*引导块*/typedef struct BLOCK0 char magic10;/文件系统魔数 char information200;/存储一些描述信息,如磁盘块大小、磁盘块数量、最多打开文件数等 unsigned short root;/根目录文件的起始
34、盘块号 unsigned char*startblock;/虚拟磁盘上数据区开始位置 block0;unsigned char*myvhard;/指向虚拟磁盘的起始地址 useropen openMAXOPENFILE;/用户打开文件表数组 int curdir;/用户打开文件表中的当前目录所在打开文件表项的位置 char currentdir80;/记录当前目录的目录名(包括目录的路径)unsigned char*startp;/记录虚拟磁盘上数据区开始位置 char my=my;/文件系统的文件名 void startsys();/进入文件系统 void my_format();/磁盘格式
35、化 void my_cd(char*dirname);/更改当前目录 void my_mkdir(char*dirname);/创建子目录 void my_rmdir(char*dirname);/删除子目录 void my_ls();/显示目录 void my_create(char*);/创建文件 void my_rm(char*);/删除文件 int my_open(char*);/打开文件 int my_close(int fd);/关闭文件 int my_write(int fd);/写文件 int do_write(int fd,char*text,int len,char wst
36、yle);/实际写文件 int my_read(int fd,int len);/读文件 int do_read(int fd,int len,char*text);/实际读文件 void my_exitsys();/退出文件系统 unsigned short findblock();/寻找空闲盘块 int findopenfile();/寻找空闲文件表项 void startsys()FILE*fp;unsigned char bufSIZE;.fcb*root;int i;myvhard=(unsigned char*)malloc(SIZE);/申请虚拟磁盘空间 memset(myvha
37、rd,0,SIZE);/将 myvhard 中前 SIZE 个字节用 0 替换并返回 myvhard if(fp=fopen(my,r)!=NULL)fread(buf,SIZE,1,fp);/将二进制文件读取到缓冲区 fclose(fp);if(strcmp(block0*)buf)-magic,10101010)printf(my is not exist,begin to creat the file.n);my_format();else for(i=0;i);strcpy(open0.exname,root-exname);open0.attribute=root-attribute
38、;open0.time=root-time;open0.date=root-date;open0.first=root-first;open0.length=root-length;open0.free=root-free;open0.dirno=5;open0.diroff=0;strcpy(open0.dir,root);open0.father=0;open0.count=0;open0.fcbstate=0;open0.topenfile=1;for(i=1;i startblock;void my_format()FILE*fp;fat*fat1,*fat2;block0*blk0;
39、time_t now;struct tm*nowtime;fcb*root;int i;blk0=(block0*)myvhard;fat1=(fat*)(myvhard+BLOCKSIZE);fat2=(fat*)(myvhard+3*BLOCKSIZE);root=(fcb*)(myvhard+5*BLOCKSIZE);strcpy(blk0-magic,10101010);strcpy(blk0-information,My Ver 1.0 n Blocksize=1KB Whole size=1000KB Blocknum=1000 RootBlocknum=2n);blk0-root
40、=5;blk0-startblock=(unsigned char*)root;for(i=0;i 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 id=FREE;fat2-id=FREE;fat1+;fat2+;now=time(NULL);nowtime=localtime(&now);.strcpy(root-,.);strcpy(root-exname,);root-attribute=0 x28;root-time=
41、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-free=1;root+;now=time(NULL);nowtime=localtime(&now);strcpy(root-,.);strcpy(root-exname,);root-attribute=0 x28;root-time=nowtime
42、-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-free=1;fp=fopen(my,w);fwrite(myvhard,SIZE,1,fp);fclose(fp);void my_cd(char*dirname)char*dir;int fd;dir=strtok(dirname,);/分解字符串为一组字符串。d
43、irname 为要分解的字符串,为分隔符字符串 if(strcmp(dir,.)=0)return;else if(strcmp(dir,.)=0)if(curdir)curdir=my_close(curdir);return;else if(strcmp(dir,root)=0)while(curdir).curdir=my_close(curdir);dir=strtok(NULL,);while(dir)fd=my_open(dir);if(fd!=-1)curdir=fd;else return;dir=strtok(NULL,);void my_mkdir(char*dirname
44、)fcb*fcbptr;fat*fat1,*fat2;time_t now;struct tm*nowtime;char textMAXTEXT;unsigned short blkno;int rbn,fd,i;fat1=(fat*)(myvhard+BLOCKSIZE);fat2=(fat*)(myvhard+3*BLOCKSIZE);opencurdir.count=0;rbn=do_read(curdir,opencurdir.length,text);fcbptr=(fcb*)text;for(i=0;i,dirname)=0&strcmp(fcbptr-exname,)=0)pri
45、ntf(Error,the dirname is already exist!n);return;fcbptr+;fcbptr=(fcb*)text;for(i=0;i free=0)break;fcbptr+;blkno=findblock();/寻找空闲盘块.if(blkno=-1)return;(fat1+blkno)-id=END;(fat2+blkno)-id=END;now=time(NULL);nowtime=localtime(&now);strcpy(fcbptr-,dirname);strcpy(fcbptr-exname,);fcbptr-attribute=0 x30;
46、fcbptr-time=nowtime-tm_hour*2048+nowtime-tm_min*32+nowtime-tm_sec/2;fcbptr-date=(nowtime-tm_year-80)*512+(nowtime-tm_mon+1)*32+nowtime-tm_mday;fcbptr-first=blkno;fcbptr-length=2*sizeof(fcb);fcbptr-free=1;opencurdir.count=i*sizeof(fcb);/把当前目录的文件读写指针定位到文件末尾 do_write(curdir,(char*)fcbptr,sizeof(fcb),2)
47、;/从指针 fcbptr 开始写一个 fcb 大小的内容到当前目录文件末尾 fd=my_open(dirname);/返回新建立的目录文件在用户打开文件数组的下标 if(fd=-1)return;fcbptr=(fcb*)malloc(sizeof(fcb);/建立新目录的.,.目录 now=time(NULL);nowtime=localtime(&now);strcpy(fcbptr-,.);strcpy(fcbptr-exname,);fcbptr-attribute=0 x28;fcbptr-time=nowtime-tm_hour*2048+nowtime-tm_min*32+now
48、time-tm_sec/2;fcbptr-date=(nowtime-tm_year-80)*512+(nowtime-tm_mon+1)*32+nowtime-tm_mday;fcbptr-first=blkno;fcbptr-length=2*sizeof(fcb);fcbptr-free=1;do_write(fd,(char*)fcbptr,sizeof(fcb),2);now=time(NULL);nowtime=localtime(&now);strcpy(fcbptr-,.);strcpy(fcbptr-exname,);fcbptr-attribute=0 x28;fcbptr
49、-time=nowtime-tm_hour*2048+nowtime-tm_min*32+nowtime-tm_sec/2;.fcbptr-date=(nowtime-tm_year-80)*512+(nowtime-tm_mon+1)*32+nowtime-tm_mday;fcbptr-first=blkno;fcbptr-length=2*sizeof(fcb);fcbptr-free=1;do_write(fd,(char*)fcbptr,sizeof(fcb),2);free(fcbptr);my_close(fd);fcbptr=(fcb*)text;fcbptr-length=op
50、encurdir.length;opencurdir.count=0;do_write(curdir,(char*)fcbptr,sizeof(fcb),2);/更新当前目录文件的内容 opencurdir.fcbstate=1;void my_rmdir(char*dirname)fcb*fcbptr,*fcbptr2;fat*fat1,*fat2,*fatptr1,*fatptr2;char textMAXTEXT,text2MAXTEXT;unsigned short blkno;int rbn,rbn2,fd,i,j;fat1=(fat*)(myvhard+BLOCKSIZE);fat