《2022年+模拟UNIX文件系统的设计及实现》由会员分享,可在线阅读,更多相关《2022年+模拟UNIX文件系统的设计及实现(36页珍藏版)》请在金锄头文库上搜索。
1、* 实践教学* 兰州理工大学计算机与通信学院2008 年秋季学期操作系统原理课程设计题目: 模拟 UNIX 文件系统专业班级:计算机一班姓名:张树伟学号:06240121 指导教师:刘嘉成绩:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 36 页 - - - - - - - - - 第 1 页总 36 页目录1.摘要. 2 2.问题描述 . 2 3.设计目的 . 2 4. 设计要求. 2 5. 详细设计. 3 5.1 界面设计 . 3 5.1 算法设计 . . 3 6.
2、 设计总结 . 4 7. 参考文献. 4 8. 致谢. 5 9.附录 . 34 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 36 页 - - - - - - - - - 第 2 页总 36 页模拟 UNIX 文件系统的设计及实现1.课程设计内容多用户的多级目录的文件系统设计。2.概述UNIX 采用树型目录结构,每个目录表称为一个目录文件。一个目录文件是由目录项组成的。每个目录项包含16B,一个辅存磁盘块 (512B)包含32 个目录项。在目录项中, 第 1、2 字节为
3、相应文件的外存i 节点号,是该文件的内部标识;后 14B 为文件名,是该文件的外部标识。所以,文件目录项记录了文件内、外部标识的对照关系。根据文件名可以找到辅存i 节点号,由此便得到该文件的所有者、存取权、文件数据的地址健在等信息。 UNIX 的存储介质以 512B 为单位划分为块,从0开始直到最大容量并顺序加以编号就成了一个文件卷,也叫文件系统。UNIX中的文件系统磁盘存储区分配图如下:0#1#2#K#K+1#K+2#K+3#n#本次课程设计是要实现一个简单的模拟UNIX 文件系统。我们在内存中开辟一个虚拟磁盘空间 (1MB)作为文件存储器,并将该虚拟文件系统保存到磁盘上(以一个文件的形式
4、),以便下次可以再将它恢复到内存的虚拟磁盘空间中。文件存储空间的管理可采用位示图方法。3.课程设计任务及要求3.1.设计任务多用户、多级目录结构文件系统的设计与实现。可以实现下列几条命令login 用户登录logout 退出当前用户dir 列文件目录creat 创建文件delete 删除文件open 打开文件close 关闭文件read 读文件write 写文件mkdir 创建目录ch 改变文件目录rd 删除目录树i 节点区文件存储区引导区管理区名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - -
5、 - 第 3 页,共 36 页 - - - - - - - - - 第 3 页总 36 页format 格式化文件系统quit 退出文件系统3.2.设计要求1) 多用户 :usr1,usr2,usr3, ,usr8 (1-8 个用户 ) 2) 多级目录:可有多级子目录;3) 具有 login (用户登录 )4) 系统初始化(建文件卷、提供登录模块)5) 文件的创建: create ( 用命令行来实现 )6) 文件的打开: open 7) 文件的读: read8) 文件的写: write 9) 文件关闭: close10) 删除文件: delete 11) 创建目录(建立子目录) :mkdir1
6、2) 改变当前目录: cd 13) 列出文件目录: dir14) 退出: logout 新增加的功能:15) 删除目录树: rd 16) 格式化文件系统: format 4.算法及数据结构4.1.算法的总体思想本课程设计是要求我们模拟UNIX 文件系统功能设计一个虚拟文件系统,依据UNIX文件系统的特点,其设计思想是:申请 1M 的内存空间来虚拟文件系统,将其以512B 每块划分 2048 块,采用位示图管理文件系统的方法, 利用其原理将第 1 块作为位图区 (512B),共有对 i 节点区和数据块区分别建立位图;每个i 节点占 16B,每块有 512/16=32个 i 节点,用 2、3 共两
7、块作为 i 节点,总共有 64 个 i 节点, 在位图区占用 8B; 其余 2045 块作为数据区 (本课设要求只用到512块),在位图区占用接近256B(2045位)。文件系统存储区分配图如下:位图区i 节点区数据区位图:用 0 表示未使用, 1 表示使用;i 节点:文件控制块 (FCB),描述文件信息的一个数据结构;数据区:存放用户数据,包括目录文件。位示图用以反映整个存储空间的分配情况,由若干字节构成,每个字节中的每一位对应文件存储器中的一块, “1”状态表示相应块已占用, “0”状态表示该块为空闲。存储块分配时,只要把找到的空闲块所对应的位由0 改为 1, 而在释放时, 只要把被释放的
8、物理块所对应的位由1 改为 0 即可。分配和释放都可以在内存的位示图上完成,而名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 36 页 - - - - - - - - - 第 4 页总 36 页且速度较快。磁盘i 节点利用在内存中生成链表或者数组的方法来生成,并且限制磁盘节点数的最大值。同样内存i 节点利用链表的方法在内存中生成。同时在往文件中写或者读的时候我们都是对内存中有内容进行读写。在该文件系统中,规定一个文件最多只能占用2 个数据块,这两个数据块可以是不连续的,其
9、块号记录在一个索引块中,该索引块称为inode 结构。读入一个文件时,先根据目录找到相应的i 节点号,将 i 节点读入主存 i 节点,建立打开文件表指向该主存i 节点,再将文件内容读入主存数据区。4.2.系统总体框架图4.3.系统总体流程图名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 36 页 - - - - - - - - - 第 5 页总 36 页4.4.各模块功能说明4.4.1format 模块功能:格式化文件系统,即初始化文件系统,相当于硬盘的格式化。将其中原有
10、的用户及用户下的文件系统全部还原初始状态,即没有任何用户和目录、文件,也就是按设计的文件系统格式重建新的文件系统。4.4.2 get_blknum和 release_blk模块功能:实现 i 节点的分配和回收;算法:当一个新的文件被建立时,在给该文件分配磁盘存储区之前,应为该文件分配存放该文件的说明信息的磁盘i 节点。反之,当从文件系统中删除某个文件时,则要首先删除它的 i 节点项。4.4.3init()模块功能:进入文件系统算法:初始化用户打开文件系表。在内存中申请一个虚拟存储空间,此空间必须大于开始文件系统是否建立?在内存中申请1M内存空间将磁盘上的文件系统读入内存Y N 用户登录模块,输
11、入用户名和密码,可以在程序中设定,不用保存在文件系统中用户名、密码对吗?执行 init(),进行初始化操作,进入用户子目录执行 command(),对用户输入的命令进行解析和执行。若数据被修改或新建立,则保存主存i 节点和数据块的内容到内存的文件系统,并写回磁盘,保存修改。若输入错误命令则显示出错信息。退出用户 (logout) 吗?用户输入 quit吗?结束执行 format(),建立文件系统N N N Y Y Y 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 36
12、页 - - - - - - - - - 第 6 页总 36 页或等于可格式化时的空间。将文件系统文件读入虚拟磁盘。4.4.4 quit()模块功能:退出文件系统函数quit() 算法:将虚拟磁盘内容保存到磁盘上。释放虚拟磁盘所占据的空间。撤消用用户打开文件表。4.4.5 Creat()模块功能:创建文件用法: creat filename 算法:分配一空目录项, 分配磁盘块。可用位示图。 填写该空目录项。 如文件长度(0) ,文件名,类型等。分配一个用户打开文件表项,并填写相关目录,读写指针=0。4.4.6 open() 模块功能:打开文件 open() 用法: open filename 算
13、法:if(该文件已打开 or 该文件不存在)报错 (出错信息 )。分配一个用户打开文件表项。4.4.7 close() 模块功能:关闭文件 close() 用法: close filename 算法:释放该文件的用户占据的内存空间。清空该文件的用户打开文件表目。4.4.8 write()模块功能:写文件 write(fd,buf,len) 用法: write filename,需要先打开文件。算法:指定写入内容长度。 buf。修改打开文件表读 /写指针。修改目录项中的文件长度。4.4.9 read() 模块功能: read(fd,buf,len) 用法: read filename, 需先打开
14、文件。算法:文件信息 .修改读 /写指针。4.4.10 delete() 模块功能:删除文件 delete() 用法: delete filename 算法:若文件不存在,报错。回收磁盘空间。回收目录项。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 36 页 - - - - - - - - - 第 7 页总 36 页4.5.该文件系统的数据结构和申明函数/ 用户(20B) typedef struct char user_name10; / 用户名char passwo
15、rd10; / 密码 User; / i 节点(32B) typedef struct short inum; / 文件 i 节点号char file_name10; / 文件名char type; / 文件类型char user_name10; / 文件所有者short iparent; / 父目录的 i 节点号short length; / 文件长度short address2; / 存放文件的地址 Inode; / 打开文件表 (16B) typedef struct short inum; / i 节点号char file_name10; / 文件名short mode; / 读写模式
16、 (1:read, 2:write, 3:read and write) short offset; / 偏移量 File_table; / 申明函数void login(void); 用户登录,如果是新用户则创建用户void init(void); 程序初始化 ,将所有 i 节点读入内存int analyse(char *); 输入参数分析,分析用户命令void save_inode(int); 将 num 号 i 节点保存到虚拟磁盘文件hd.dat int get_blknum(void); 申请一个数据块void read_blk(int); 将 i 节点号为 num 的文件读入 tem
17、p 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 36 页 - - - - - - - - - 第 8 页总 36 页void write_blk(int); 将 temp 的内容写入 hd.dat的数据区void release_blk(int); 释放文件块号为 num 的文件占用的空间void pathset(); 打印当前路径void deltree(int innum); 实现删除目录树函数int check(int); 检查用户权限/ 用户命令处理函数voi
18、d help(void); 命令提示帮助函数void cd(void); 改变当前目录void dir(void); 显示当前目录下所有文件和目录void mkdir(void); 创建目录void rd(void); 删除目录void creat(void); 创建文件void open(void); 打开void read(void); 读文件void write(void); 写文件void close(void); 关闭文件void del(void); 删除文件void logout(void); 用户注销void command(void); 命令管理函数void format(v
19、oid); 格式化虚拟磁盘5.程序设计与实现5.1.主要函数列表函数原型功能入口、出口参数说明void login(void) 用户登陆void init(void) 程序初始化int analyse(char *) 输入参数分析命令行字符串void save_inode(int) 保存 i 节点到虚拟磁盘文件i 节点号int get_blknum(void) 分配一个磁盘块void read_blk(int) 读磁盘快内容i 节点号void write_blk(int) 写磁盘块i 节点号void release_blk(int) 释放一个磁盘块i 节点号void pathset(); 打印
20、当前路径void deltree(int innum); 实现删除目录树函数i 节点号int check(int); 检查用户权限i 节点号名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 9 页,共 36 页 - - - - - - - - - 第 9 页总 36 页void help(void) 命令提示帮助函数void dir(void) 显示当前目录下所有文件和目录void mkdir(void) 创建目录void creat(void) 创建文件void open(void)
21、 打开文件void read(void) 读文件void write(void) 写文件void close(void) 关闭文件void del(void) 删除文件void logout(void) 用户登出void command(void) 命令管理函数void rd(void) 删除目录void format(void); 格式化虚拟磁盘5.2.函数之间的关系5.3.程序流程图各功能模块流程图main() login() init() command() analyse() help() cd() dir() mkdir() creat() open() read() write()
22、 close() del() logout() cls() errcmd() format() quit() rd() save_inode() read_blk() get_blknum() write_blk() release_blk() delet() 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 10 页,共 36 页 - - - - - - - - - 第 10 页总 36 页是否否是提示输入用户名和密码用户名是否存在创建新用户读入用户信息到内存开始密码是否正确结束用户
23、登陆login() 是是否否遍历 i 节点区argv1= ” .”目录是否存在找到的目录i 节点号送当前目录inum_cur 当前目录的父i节点号送当前目录 inum_cur 开始结束改变当前目录cd() 是是否否遍历 i 节点区i 节点的父节点是否为当前目录i 节点区是否遍历完输出文件名或目录名开始结束显示目录dir() 读入位示图信息到内存读入 i 节点信息到内存当前目录为根目录初始化打开文件表结束开始初始化函数init() 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 11
24、页,共 36 页 - - - - - - - - - 第 11 页总 36 页是是否否遍历 i 节点区要创建的目录是否存在是否有空的i 节点遍历 i 节点区分配一个目录i 节点开始结束创建目录 mkdir() 是是否否遍历 i 节点区要创建的文件是否存在是否有空的i 节点遍历 i 节点区分配一个文件i 节点开始结束创建文件 creat() 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 12 页,共 36 页 - - - - - - - - - 第 12 页总 36 页是否是否是否遍
25、历 i 节点区要打开的文件是否存在提示输入打开模式将打开文件信息写入打开文件信息表file_array 遍历打开文件表 file_array 文件是否已经打开提示输入开始位置和读字节数调用读块操作,读出块内字符模式是否为可读开始结束开始结束打开文件 open() 读文件 read() 是否是否遍历打开文件表 file_array 文件是否已经打开提示输入写入字节数调用写块操作,写入块内字符模式是否为可写是否遍历打开文件表 file_array 文件是否已经打开将打开文件表项标志位置-1 file_arrayi.inum = -1 开始结束写文件 write() 开始结束关闭文件close()
26、名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 13 页,共 36 页 - - - - - - - - - 第 13 页总 36 页是否遍历 i 节点区要删除的文件是否存在释放文件对应的i 节点区inode_arrayi.inum = -1 释放两个磁盘块文件是否大于的一块释放一个磁盘块是否开始结束删除文件del() 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 14 页
27、,共 36 页 - - - - - - - - - 第 14 页总 36 页开始遍历 i 节点区是待删除目录吗?遍历子目录子目录为空吗?是文件吗?是空目录吗?结束调用 delet()删除目录或文件是空目录吗?删除目录树rd() 是是否否否否否是是是是否遍历位示图表查找空闲块 bitmap 是否有空闲块分配一块,将位示图位置置 1 。 bitmapi = 1 返回找到的空闲块号将位示图位置置 0 。bitmapi = 0 清空块内容开始结束分配磁盘块get_blk() 开始结束释放磁盘块release_blk(int)名师资料总结 - - -精品资料欢迎下载 - - - - - - - - -
28、- - - - - - - - - 名师精心整理 - - - - - - - 第 15 页,共 36 页 - - - - - - - - - 第 15 页总 36 页5.4.源程序/*main.c*/ #include head.h char choice; int argc; / 用户命令的参数个数char *argv5; / 用户命令的参数int inum_cur; / 当前目录char temp2*BLKSIZE; / 缓冲区User user; / 当前的用户char bitmapBLKNUM; / 位图数组Inode inode_arrayINODENUM; / i 节点数组File
29、_table file_arrayFILENUM; / 打 开 文件表数组char image_name10 = hd.dat; / 文 件 系统名称FILE *fp; / 打 开 文件指针/创建映像 hd,并将所有用户和文件清除void format(void) FILE *fp; int i; Inode inode; printf(Will be to format filesystem.n); printf(WARNING:ALL DATA ON THIS FILESYSTEM WILL BE LOST!n); printf(Proceed with Format(Y/N)?); sc
30、anf(%c, &choice); gets(temp); if(choice = y) | (choice = Y) if(fp=fopen(image_name, w+b) = NULL) printf(Cant create file %sn, image_name); exit(-1); for(i = 0; i BLKSIZE; i+) fputc(0, fp); inode.inum = 0; strcpy(inode.file_name, /); 是否输出给定i 节点对应的第 1 块内容文件是否大于1 块输出给定i 节点对应的第 2 块内容是否将缓冲区buf 内容写入第 1 块b
31、uf 内容是否大于512 字节将缓冲区 buf 的 512字节后面的内容写入第 2 块开始结束写磁盘块write_blk(int)开始结束读磁盘块read_blk(int)名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 16 页,共 36 页 - - - - - - - - - 第 16 页总 36 页inode.type = d; strcpy(inode.user_name, all); inode.iparent = 0; inode.length = 0; inode.add
32、ress0 = -1; inode.address1 = -1; fwrite(&inode, sizeof(Inode), 1, fp); inode.inum = -1; for(i = 0; i 31; i+) fwrite(&inode, sizeof(Inode), 1, fp); for(i = 0; i BLKNUM*BLKSIZE; i+) fputc(0, fp); fclose(fp); / 打开文件 user.txt if(fp=fopen(user.txt, w+) = NULL) printf(Cant create file %sn, user.txt); exit
33、(-1); fclose(fp); printf(Filesystem created successful.Please first login!n); return ; / 功能: 用户登陆,如果是新用户则创建用户void login(void) char *p; int flag; char user_name10; char password10; char file_name10 = user.txt; do printf(login:); gets(user_name); printf(password:); p=password; while(*p=getch() if(*p =
34、 0x0d) /当输入回车键时,0x0d 为回车键的 ASCII 码 *p=0; /将输入的回车键转换成空格break; printf(*); /将输入的密码以 * 号显示p+; flag = 0; if(fp = fopen(file_name, r+) = NULL) printf(nCant open file %s.n, file_name); printf(This filesystem not exist, it will be create!n); format(); login(); while(!feof(fp) fread(&user, sizeof(User), 1, f
35、p); / 已经存在的用户 , 且密码正确if(!strcmp(user.user_name, user_name) & 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 17 页,共 36 页 - - - - - - - - - 第 17 页总 36 页!strcmp(user.password, password) fclose(fp); printf(n); return ; / 已经存在的用户 , 但密码错误else if(!strcmp(user.user_name, use
36、r_name) printf(nThis user is exist, but password is incorrect.n); flag = 1; fclose(fp); break; if(flag = 0) break; while(flag); / 创建新用户if(flag = 0) printf(nDo you want to creat a new user?(y/n):); scanf(%c, &choice); gets(temp); if(choice = y) | (choice = Y) strcpy(user.user_name, user_name); strcpy
37、(user.password, password); fwrite(&user, sizeof(User), 1, fp); fclose(fp); return ; if(choice = n) | (choice = N) login(); / 功能: 将所有 i 节点读入内存void init(void) int i; if(fp = fopen(image_name, r+b) = NULL) printf(Cant open file %s.n, image_name); exit(-1); / 读入位图for(i = 0; i BLKNUM; i+) bitmapi = fgetc
38、(fp); / 显示位图/ 读入 i 节点信息for(i = 0; i INODENUM; i+) fread(&inode_arrayi, sizeof(Inode), 1, fp); / 显示 i 节点/ 当前目录为根目录inum_cur = 0; / 初始化打开文件表for(i = 0; i FILENUM; i+) file_arrayi.inum = -1; / 功能 : 分析用户命令, 将分析结果填充argc和 argv / 结果: 0-14 为系统命令 , 15为命令错误int analyse(char *str) int i; char temp20; char *ptr_ch
39、ar; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 18 页,共 36 页 - - - - - - - - - 第 18 页总 36 页char *syscmd=help, cd, dir, mkdir, creat, open, read, write, close, delete, logout, clear,format,quit,rd; argc = 0; for(i = 0, ptr_char = str; *ptr_char != 0; ptr_char+) if(*
40、ptr_char != ) while(*ptr_char != & (*ptr_char != 0) tempi+ = *ptr_char+; argvargc = (char *)malloc(i+1); strncpy(argvargc, temp, i); argvargci = 0; argc+; i = 0; if(*ptr_char = 0) break; if(argc != 0) for(i = 0; (i 15) & strcmp(argv0, syscmdi); i+); return i; else return 15; / 功能: 将 num 号 i 节点保存到 hd
41、.dat void save_inode(int num) if(fp=fopen(image_name, r+b) = NULL) printf(Cant open file %sn, image_name); exit(-1); fseek(fp, 512+num*sizeof(Inode), SEEK_SET); fwrite(&inode_arraynum, sizeof(Inode), 1, fp); fclose(fp); / 功能: 申请一个数据块int get_blknum(void) int i; for(i = 0; i 512) add1 = inode_arraynum
42、.address1; if(fp = fopen(image_name, r+b) = NULL) printf(Cant open file %s.n, image_name); exit(-1); fseek(fp, 1536+add0*BLKSIZE, SEEK_SET); ch = fgetc(fp); for(i=0; (i len) & (ch != 0) & (i = 512) fseek(fp, 1536+add1*BLKSIZE, SEEK_SET); ch = fgetc(fp); for(; (i len) & (ch != 0); i+) tempi = ch; ch
43、= fgetc(fp); tempi = 0; fclose(fp); / 功能: 将 temp的内容输入 hd 的数据区void write_blk(int num) int i, len; int add0, add1; add0 = inode_arraynum.address0; len = inode_arraynum.length; if(fp = fopen(image_name, r+b) = NULL) printf(Cant open file %s.n, image_name); exit(-1); fseek(fp, 1536+add0*BLKSIZE, SEEK_SE
44、T); for(i=0; (ilen)&(tempi!=0)&(i 512); i+) fputc(tempi, fp); if(i = 512) add1 = inode_arraynum.address1; fseek(fp, 1536+add1*BLKSIZE, SEEK_SET); for(; (i len) & (tempi != 0); i+) fputc(tempi, fp); fputc(0, fp); fclose(fp); / 功能: 释放文件块号为 num的文件占用的空间void release_blk(int num) 名师资料总结 - - -精品资料欢迎下载 - -
45、- - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 20 页,共 36 页 - - - - - - - - - 第 20 页总 36 页FILE *fp; if(fp=fopen(image_name, r+b) = NULL) printf(Cant open file %sn, image_name); exit(-1); bitmapnum = 0; fseek(fp, num, SEEK_SET); fputc(0, fp); fclose(fp); / 功能: 显示帮助命令void help(void) printf(comm
46、and: n help - show help menu n clear - clear the screen n cd - change directory n mkdir - make directory n creat - create a new file n open - open a exist file n read - read a file n write - write something to a file n close - close a file n delete - delete a exist file n format - format a exist fil
47、esystem n logout - exit user n rd - delete a directory n quit - exit this systemn); /设置文件路径void pathset() char path50; int m,n; if(inode_arrayinum_cur.inum = 0) strcpy(path,user.user_name); else strcpy(path,user.user_name); m=0; n=inum_cur; while(m != inum_cur) while(inode_arrayn.iparent != m) n = i
48、node_arrayn.iparent; strcat(path,/); strcat(path,inode_arrayn.file_name); m = n; n = inum_cur; printf(%s,path); / 功能: 切换目录 (cd . 或者 cd dir1) void cd(void) int i; if(argc != 2) printf(Command cd must have two args. n); return ; if(!strcmp(argv1, .) inum_cur = inode_arrayinum_cur.iparent; else 名师资料总结
49、- - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 21 页,共 36 页 - - - - - - - - - 第 21 页总 36 页 / 遍历 i 节点数组for(i = 0; i 0)& (inode_arrayi.type=d)& (inode_arrayi.iparent=inum_cur)& !strcmp(inode_arrayi.file_name,argv1)& check(i) break; if(i = INODENUM) printf(This directory isnt e
50、xsited.n); else inum_cur = i; / 功能 : 显示当前目录下的子目录和文件(dir) void dir(void) int i; int dcount=0,fcount=0; short bcount=0; if(argc != 1) printf(Command dir must have one args. n); return ; / 遍历 i 节点数组 , 显示当前目录下的子目录和文件名for(i = 0; i 0) & (inode_arrayi.iparent = inum_cur) if(inode_arrayi.type = d & check(i)
51、 dcount+; printf(%-20sn, inode_arrayi.file_name); if(inode_arrayi.type = - & check(i) fcount+; bcount+=inode_arrayi.length; printf(%-20s%12d bytesn, inode_arrayi.file_name,inode_arrayi.length); printf(n %d file(s)%11d bytesn,fcount,bcount); printf( %d dir(s) %11d bytes FreeSpacen,dcount,1024*1024-bc
52、ount); / 功能: 删除目录树 (rd dir1) void rd() int i,j,t,flag=0; if(argc != 2) printf(Command delete must have one args. n); return ; for(i = 0; i 0) &/ 是否为空名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 22 页,共 36 页 - - - - - - - - - 第 22 页总 36 页(inode_arrayi.iparent = inum_
53、cur) & (inode_arrayi.type = d)& (!strcmp(inode_arrayi.file_name,argv1) chk=check(i);/检查用户权限if(chk!=1) printf(This directory is not your !n); return ; else j=inode_arrayi.inum; for(t=0;t0)& (inode_arrayt.iparent=j)& (inode_arrayi.type = -) delet(t);/目录下有文件则删除else if(inode_arrayt.inum0)& (inode_arrayt
54、.iparent=j)& (inode_arrayi.type = d) delet(t);/目录下有空目录则删除 if(t = INODENUM) delet(j);/下层目录为空删除之 if(i = INODENUM) delet(i);/待删除目录为空删除之return; / 功能 : 在当前目录下创建子目录(mkdir dir1) void mkdir(void) int i; if(argc != 2) printf(command mkdir must have two args. n); return ; / 遍历 i 节点数组 , 查找未用的 i 节点for(i = 0; i
55、INODENUM; i+) if(inode_arrayi.inum 0) break; if(i = INODENUM) printf(Inode is full.n); exit(-1); inode_arrayi.inum = i; strcpy(inode_arrayi.file_name, argv1); inode_arrayi.type = d; strcpy(inode_arrayi.user_name,user.user_name); inode_arrayi.iparent = inum_cur; inode_arrayi.length = 0; save_inode(i)
56、; / 功能: 在当前目录下创建文件 (creat file1) void creat(void) int i; if(argc != 2) printf(command creat must have one args. n); return ; for(i = 0; i 0) & 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 23 页,共 36 页 - - - - - - - - - 第 23 页总 36 页(inode_arrayi.type = -) & !strcmp(i
57、node_arrayi.file_name, argv1) printf(This file is exsit.n); return ; for(i = 0; i INODENUM; i+) if(inode_arrayi.inum 0) break; if(i = INODENUM) printf(Inode is full.n); exit(-1); inode_arrayi.inum = i; strcpy(inode_arrayi.file_name, argv1); inode_arrayi.type = -; strcpy(inode_arrayi.user_name, user.
58、user_name); inode_arrayi.iparent = inum_cur; inode_arrayi.length = 0; save_inode(i); / 功能: 打开当前目录下的文件 (open file1) void open() int i, inum, mode, filenum,chk; if(argc != 2) printf(command open must have one args. n); return ; for(i = 0; i 0) & (inode_arrayi.type = -) & !strcmp(inode_arrayi.file_name
59、,argv1) break; if(i = INODENUM) printf(The file you want to open doesnt exsited.n); return ; inum = i; chk=check(i); if(chk!=1) printf(This file is not your !n); return ; printf(Please input open mode:(1: read, 2: write, 3: read and write):); scanf(%d, &mode); gets(temp); if(mode 3) printf(Open mode
60、 is wrong.n); return; for(i = 0; i FILENUM; i+) if(file_arrayi.inum 0) break; if(i = FILENUM) printf(The file table is full, please close some file.n); return ; filenum = i; file_arrayfilenum.inum = inum; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 24 页,共 36 页 - -
61、 - - - - - - - 第 24 页总 36 页strcpy(file_arrayfilenum.file_name, inode_arrayinum.file_name); file_arrayfilenum.mode = mode; file_arrayfilenum.offset = 0; printf(Open file %s by , file_arrayfilenum.file_name); if(mode = 1) printf(read only.n); else if(mode = 2) printf(write only.n); else printf(read an
62、d write.n); / 功能: 从文件中读出字符 (read file1) void read() int i, start, num, inum; if(argc != 2) printf(command read must have one args. n); return; for(i = 0; i 0) & !strcmp(file_arrayi.file_name,argv1) break; if(i = FILENUM) printf(Open %s first.n, argv1); return ; else if(file_arrayi.mode = 2) printf(C
63、ant read %s.n, argv1); return ; inum = file_arrayi.inum; printf(The length of %s:%d.n, argv1, inode_arrayinum.length); if(inode_arrayinum.length 0) printf(The start position:); scanf(%d, &start); gets(temp); if(start=inode_arrayinum.length) printf(Start position is wrong.n); return; printf(The bytes
64、 you want to read:); scanf(%d, &num); gets(temp); if(num = 0) printf(The num you want to read is wrong.n); return ; read_blk(inum); for(i = 0; (i num) & (tempi != 0); i+) printf(%c, tempstart+i); printf(n); / 功能: 向文件中写入字符 (write file1) void write() int i, inum, length; if(argc != 2) printf(Command w
65、rite must have one 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 25 页,共 36 页 - - - - - - - - - 第 25 页总 36 页args. n); return ; for(i = 0; i 0)& !strcmp(file_arrayi.file_name,argv1) break; if(i = FILENUM) printf(Open %s first.n, argv1); return ; else if(file_arrayi.mo
66、de = 1) printf(Cant write %s.n, argv1); return ; inum = file_arrayi.inum; printf(The length of %s:%dn, inode_arrayinum.file_name, inode_arrayinum.length); if(inode_arrayinum.length = 0) printf(The length you want to write(0-1024):); scanf(%d, &length); gets(temp); if(length 1024) printf(Input wrong.
67、n); return ; inode_arrayinum.length = length; inode_arrayinum.address0 = get_blknum(); if(length 512) inode_arrayinum.address1 = get_blknum(); save_inode(inum); printf(Input the data(Enter to end):n); gets(temp); write_blk(inum); else printf(This file cant be written.n); / 功能: 关闭已经打开的文件 (close file1
68、) void close(void) int i; if(argc != 2) printf(Command close must have one args. n); return ; for(i = 0; i 0) & !strcmp(file_arrayi.file_name, argv1) break; if(i = FILENUM) printf(This file doesnt be opened.n); return ; else file_arrayi.inum = -1; printf(Close %s successful!n, argv1); 名师资料总结 - - -精品
69、资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 26 页,共 36 页 - - - - - - - - - 第 26 页总 36 页/删除目录树void delet(int innum) /*int chk; chk=check(innum); if(chk!=1) /printf(This directory is not yours !n); return ; */ inode_arrayinnum.inum = -1; if(inode_arrayinnum.length = 0) release_blk
70、(inode_arrayinnum.address0); if(inode_arrayinnum.length = 512) release_blk(inode_arrayinnum.address1); save_inode(innum); / 功能: 删除文件 (delete file1) void del(void) int i,chk; if(argc != 2) printf(Command delete must have one args. n); return ; for(i = 0; i 0) & (inode_arrayi.type = -) & !strcmp(inode
71、_arrayi.file_name, argv1) break; if(i = INODENUM) printf(This file doesnt exist.n); return ; chk=check(i); if(chk!=1) printf(This file is not your !n); return ; /*inode_arrayi.inum = -1; if(inode_arrayi.length 0) release_blk(inode_arrayi.address0); if(inode_arrayi.length 512) release_blk(inode_array
72、i.address1); save_inode(i);*/ delet(i); / 功能: 退出当前用户 (logout) void logout() char choice; printf(Do you want to exit this user(y/n)?); scanf(%c, &choice); gets(temp); if(choice = y) | (choice = Y) printf(nCurrent user exited!nPlease to login by other user!n); login(); return ; 名师资料总结 - - -精品资料欢迎下载 -
73、- - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 27 页,共 36 页 - - - - - - - - - 第 27 页总 36 页/检查当前 I 节点的文件是否属于当前用户int check(int i) int j; char *uuser,*fuser; uuser=user.user_name; fuser=inode_arrayi.user_name; j=strcmp(fuser,uuser); if(j=0) return 1; else return 0; / 功能: 退出文件系统 (quit) void qui
74、t() char choice; printf(Do you want to exist(y/n):); scanf(%c, &choice); gets(temp); if(choice = y) | (choice = Y) exit(0); / 功能: 显示错误void errcmd() printf(Command Error!n); /清空内存中存在的用户名free_user() int i; for(i=0;i10;i+) user.user_namei=0; / 功能 : 循环执行用户输入的命令, 直到logout / help, cd, dir, mkdir, creat, o
75、pen,read, write, close, delete, logout, clear, format,quit,rd void command(void) char cmd100; system(cls); do pathset(); gets(cmd); switch(analyse(cmd) case 0: help(); break; case 1: cd(); break; case 2: dir(); break; case 3: mkdir(); break; case 4: creat(); break; case 5: open(); break; case 6: rea
76、d(); break; case 7: write(); break; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 28 页,共 36 页 - - - - - - - - - 第 28 页总 36 页case 8: close(); break; case 9: del(); break; case 10: logout(); break; case 11: system(cls); break; case 12: format(); init(); free_user(); l
77、ogin(); break; case 13: quit(); break; case 14: rd(); break; case 15: errcmd(); break; default: break; while(1); / 主函数int main(void) login(); init(); command(); return 0; /* head.h */ #include #include #include #include #define BLKSIZE 512 / 数 据 块的大小#define BLKNUM 512 / 数 据 块的块数#define INODESIZE 32
78、/ i 节点的大小#define INODENUM 32 / i 节点的数目#define FILENUM 8 / 打 开 文 件表的数目/ 用户(20B) typedef struct char user_name10; / 用户名char password10; / 密码 User; / i 节点(32B) typedef struct short inum; / 文件 i 节点号char file_name10; / 文件名char type; / 文件类型char user_name10; / 文件所有者名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - -
79、- - - - - - - - 名师精心整理 - - - - - - - 第 29 页,共 36 页 - - - - - - - - - 第 29 页总 36 页short iparent; / 父目录的 i 节点号short length; / 文件长度short address2; / 存放文件的地址 Inode; / 打开文件表 (16B) typedef struct short inum; / i 节点号char file_name10; / 文件名short mode; / 读 写 模 式(1:read, 2:write, / 3:read and write) short off
80、set; / 偏移量 File_table; / 申明函数void login(void); void init(void); int analyse(char *); void save_inode(int); int get_blknum(void); void read_blk(int); void write_blk(int); void release_blk(int); void pathset(); void delet(int innum); int check(int i); / 用户命令处理函数void help(void); void cd(void); void dir
81、(void); void mkdir(void); void creat(void); void open(void); void read(void); void write(void); void close(void); void del(void); void logout(void); void command(void); void rd(); void quit(); 6.使用说明1.本程序首次运行(假设当前硬盘目录下还未建立user.txt和 hd.dat文件)时会提示找不到 user.txt文件,虚拟文件系统不存在,此时程序会提示你是否要建立文件系统,得到你的确认后程序将格式
82、化虚拟磁盘建立虚拟文件系统,并在磁盘当前目录里生成这两个文件。文件系统建立后便出现用户登录提示。2.系统首次登录时,当输入用户名和密码后,则提示是否要新建用户。得到用户确认名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 30 页,共 36 页 - - - - - - - - - 第 30 页总 36 页后即建立了该用户并登录到该用户目录下。即可在该用户下输入命令进行文件、目录的操作。3.当文件系统建好后,也有了新的用户,以后就可以用用户名和密码登录该文件系统了。当再次登录系统时,若输
83、入的用户名不存在,则提示是否要新建用户,得到用户确认后就可以建立新的用户。当要使用其他用户时,则需要先使用注销用户命令logout 退出当前用户,再按提示输入新的用户名和密码进入新的用户。4.执行 help 命令的效果截图:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 31 页,共 36 页 - - - - - - - - - 第 31 页总 36 页5.当想要清除该文件系统中所有内容时,可以使用format 命令,该命令会象 DOS 里的format 命令一样将你系统中的所有信息
84、全部消除,包括所有用户和所有文件及目录,因此该命令要慎用。6.以下是实现建立、查看、进入、退出、删除子目录的功能:7.以下是实现新建、打开、读、写、关闭、删除文件的功能:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 32 页,共 36 页 - - - - - - - - - 第 32 页总 36 页8.本文件系统实现了权限管理,任何用户只能访问自己创建的目录和读写自己创建的文件,禁止其他用户访问。9.quit 命令直接退出程序。名师资料总结 - - -精品资料欢迎下载 - - -
85、- - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 33 页,共 36 页 - - - - - - - - - 第 33 页总 36 页(该程序操作要点说明:要先打开一个文件,然后才能往该文件中写内容。) 7.结论、问题及解决办法模拟实现了 UNIX 文件系统,较好地实现了课程设计的任务和要求及各个功能。本系统的功能较完善,实现了文件系统的初始建立,格式化操作,用户的切换,用户权限管理,删除目录树等新增加的功能 (改进) , 完整地实现了课程设计所要求的基本功能:新建用户、文件、目录,删除文件、目录,进入、退出目录,文件的打开、读、写、关闭
86、等。在验收时,很好的实现了完整地删除目录树的功能,命令提示符中能显示当前的用户和路径,用 dir 命令查看时能查看文件类型、 长度,能统计当前目录下的文件个数及总大小、剩余空间和目录个数,还实现了切换用户的功能、格式化文件系统的功能。在验收时还是有点小问题一直没得到很好解决,就是用当前用户进行对该文件系统格式化后,还可以用刚才的那个当前用户登录,里面的文件信息依然存在,当时和项国富老师一起查找还是没有找到问题的所在,也未得到解决(截图如下 )。通过今天上午和杨华同学查找、调试,进行了有针对性的讨论:为什么格式化之前的那个用户( user1)在格式化后还存在(程序未关闭) ,而当程序关闭后再执行
87、程序进入后并不存在这个用户,而且user.txt文件长度为,内容为空,一切正常。也就是说格式化是很成功的,其问题不是出在格式化功能模块。这说明在格式化后程序未退出前,该用户名还在内存中没有被释放, 即 user.user_name 数组中的用户名还存在, 那么问题很有可能出在调用 login()功能模块。我们又仔细分析了login()功能模块,在执行下面的这段程序时应该将user.txt文件中的内容(此时该文件无内容)读入user.user_name 数组中,应该该数组为空,名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精
88、心整理 - - - - - - - 第 34 页,共 36 页 - - - - - - - - - 第 34 页总 36 页这样程序就会判断该新输入的用户不存在,则会跳出执行后面建立新用户的程序段,然而并非如此。fp = fopen(file_name, r+) while(!feof(fp) fread(&user, sizeof(User), 1, fp);/ 已经存在的用户 , 且密码正确if(!strcmp(user.user_name, user_name) & !strcmp(user.password, password) fclose(fp); printf(n); retur
89、n ; 因此我们用 printf(“ %s” , user.user_name) 语句进行测试,测试结果user.user_name 里面的内容仍然是 user1,说明 fread(&user, sizeof(User), 1, fp)并没有把 user.txt里面的空内容写入 user.user_name中,那这又是为什么呢?接着我和杨华同学打开VC6.0 帮助文档,认真研究文档中 fread(buffer,size,count,fp)函数,终于找出了问题所在:原来该函数有一个特性,即“If size or count is 0, fread returns 0 and the buffer
90、 contents are unchanged” ,意思是说如果要读写的字节数或要进行读写多少个size字节的数据项为 0,则 fread函数返回 0 并且不改变读入数据的存放地址中的原有内容。在这里正好格式化后的user.txt文件的字节数为,因此 fread(&user, sizeof(User), 1, fp)并没有改变数组 user中的原有内容,即user.user_name的内容还是 user1。找到了问题的所在,就好解决了,因此只要格式化后先调用init()函数,初始化 i 节点,再将 user.user_name 中的内容填入 0 ,我们就写了下面这个free_user()函数进
91、行调用,最后再调用 login()函数。问题得到彻底解决。(见上面的使用说明第5 条的截图)free_user() int i; for(i=0;i10;i+) user.user_namei=0; 8.收获与体会经过两周的共同努力,在项国富老师提供的源代码基础上,我们将程序按要求修改完善, 使其能实现课程设计要求的基本功能并增加了一两个新的功能(权限管理与删除目录) 。操作系统是计算机科学与技术专业中的一门重要基础课,目的是让我们了解操作系统名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - -
92、- 第 35 页,共 36 页 - - - - - - - - - 第 35 页总 36 页的基本概念,理解计算机系统的资源如何组织,操作系统如何有效地管理这些系统资源,用户如何通过操作系统与计算机系统打交道。通过课程设计,可以进一步理解在计算机系统上运行的其它各类操作系统,并懂得在操作系统的支持下建立自己的应用系统。操作系统课程设计,对于训练我们掌握程序设计、熟悉上机操作和程序调试技术都有重要作用。重点培养我们的思维能力、创新能力和排错能力。通过课程设计,进一步融会贯通教材内容,掌握程序各功能模块的工作原理,相互联系和来龙去脉,完整地建立系统的概念。激发我的学习热情和主动性,培养我的独立工作能力,在实践活动中,将所学知识综合运用,增长才干,并积累经验。对编程语言又有了更深一层次的认识,并对其的编程能力有所加强,但还是很多的不足有待改进,对于编程来说还需要大量的实践,才能在发现问题和解决问题中前进与提高。最后,向辛勤指导我们的邵志远老师和项国富老师表示深深的谢意!并祝二位恩师新年快乐,身体健康,工作顺利,万事如意! 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 36 页,共 36 页 - - - - - - - - -