操作系统实验报告-文件管理系统-源程序_第1页
操作系统实验报告-文件管理系统-源程序_第2页
操作系统实验报告-文件管理系统-源程序_第3页
操作系统实验报告-文件管理系统-源程序_第4页
操作系统实验报告-文件管理系统-源程序_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

操作系统实验报告操作系统实验报告题目: 文件管理系统班级:目录一、 实践内容 31.1实验内容 32.实验原理 43、实验要求 4二、 实验的目的及意义 4三、 详细设计 53.1功能设计 53.2结构设计 63.3核心算法 113.4数据结构 11四、调试分析 134.1运行环境 134.2调试分析 13五、缺点及改进 135.1实验缺点 135.2实验改进 13六、实验总结 13七、参考文献 14八、附录 148.1个人心得 148.2源程序 15实践内容1.1实验内容通过一个简单的二级文件系统设计,加深对文件系统的内部功能以及内部实现的理解。要求模拟采用二级目录结构的磁盘文件系统的文件操作能实现以下几条命令,用输入命令来模拟用户程序中调用的文件操作:Login用户登录用户输入用户名和密码,在passwd文件中查找是否有此用户,核对密码。正确则登陆成功,当前目录设定到当前用户文件夹下。format格式化初始化超级块,初始化主目录,初始化管理员admin目录,初始化用户目录,初始化用户passwd文件。create创建文本文件查找当前目录下是否有同名文件,是则退出,否则让用户输入文本文件内容,以‘###’结束。申请硬盘空间,申请失败则结束。将文件内容写入硬盘空间。修改当前目录的结构,修改超级块。cdir创建文件夹查找当前目录下是否有同名文件,是则退出,否则,申请硬盘空间,申请失败则结束。将文件夹内容写入硬盘空间。修改当前目录的结构,修改超级块,写入模拟硬盘。readedit读取和追加文本文件Read查找当前目录下是否该文件,没有则退出,否则调用access()权限判断,有权限则判断是不是文件,不是则退出,是文件则读取文件并显示。Edit调用读取文件模块,读取成功则用户输入追加的内容,如果追加的内容大于一个硬盘分配空间则申请分配空间,失败则退出,申请成功则保存文件。access(文件名)权限判断,先判断当前目录是否有该文件,在当前目录的硬盘空间找到该文件,判断当前登录用户是哪个组,判断是否该用户创建,判断该文件的可见级别。如果是该用户创建的则有读写权限如果当前用户是管理员组的也具有读写权限如果该文件是用户可查看文件则都具有权限。cd进入子目录或上级目录,查找当前目录是否有该子目录,没有则退出,调用access()判断当前用户是否有权限,无则退出,有则读取该子目录的目录,将当前目录指向该目录。attr(文件名)查看文件或者文件夹的属性,先查找当前目录下是否有该文件或目录,有则判断文件是否系统文件,是否文本文件,是否目录,由谁创建,属于什么组,占用的空间和目录。将其全部显示出来。Del删除文件或目录。查找当前目录是否有该文件名,没有则退出,有则调用access()判断是否有权限,有则判断是否为系统文件,是则无法删除,不是则判断是否是文件,是文件则直接删除,不是则判断是否文件夹,是文件夹则判断该文件夹下是否有文件,有文件则无法删除。提示用户是否删除,确认则删除文件,修改当前文件夹目录和硬盘空间结构,修改超级块,写入模拟硬盘。Dir列文件目录(列出文件名、物理地址、保护码和文件长度)2.实验原理文件系统管理中用到的数据结构有:(1)首先应确定文件系统的数据结构:主目录、子目录及活动文件等。主目录和子目录都以文件的形式存放于磁盘,这样便于查找和修改。(2)用户创建的文件,可以编号存储于磁盘上。如:file0,file1,file2…并以编号作为物理地址,在目录中进行登记。3、实验要求(1)设计一个10个用户的文件系统,每次用户可保存10个文件,一次运行用户可以打开5个文件。(2)程序采用二级文件目录(即设置主目录MFD)和用户文件目录(UFD)。另外,为打开文件设置了运行文件目录(AFD)。(3)为了便于实现,对文件的读写作了简化,在执行读写命令时,只需改读写指针,并不进行实际的读写操作。(4)文件保护简单使用了三位保护码:允许读写执行、对应位为1,对应位为0,则表示不允许读写、执行。实验的目的及意义课程设计目的使学生熟悉文件管理系统的设计方法;加深对所学各种文件操作的了解及其操作方法的特点。通过模拟文件系统的实现,深入理解操作系统中文件系统的理论知识,加深对教材中的重要算法的理解。同时通过编程实现这些算法,更好地掌握操作系统的原理及实现方法,提高综合运用各专业课知识的能力。详细设计3.1功能设计Help 显示命令帮助dir 显示当前目录下的文件和文件夹logout 注销exit 退出系统create[文件名] 创建文本文件cdir[目录名] 创建文件夹read[文件名] 读取一个文件最多可同时读取五个close[文件名] 关闭一个文件edit[文件名] 编辑一个文件cd[目录名] 进子目录或者上级目录attr[文件名] 显示该文件的属性del[文件名] 删除文件rename[文件名] 重命名3.2结构设计1)总设计结构图 2)目录结构示意图3)流程图 编辑功能流程图 创建文件流程图删除文件功能流程图 3.3核心算法boolFormat(void); //格式化boolinstall(void); //装载虚拟硬盘的数据voidlogin(void); /用户登陆voidshowMenu(void);//显示功能菜单boolonAction(void);//用户选择功能并执行voidshowDir();//显示当前文件夹里面文件的信息voidlogout();//注销voidcreateFile(stringstr);//创建文件voidcreateDir(stringstr);//创建文件夹boolread(stringstr);//读取文件voideditFile(stringstr);//编辑文件intvisit(stringstr);//打开一个文件夹voidattrib(stringstr);//显示文件属性voidDelete(stringstr);//删除一个文件intrename(stringstr);//重命名一个文件3.4数据结构/*常变量*/constunsignedintBLOCK_SIZE=512; //块长constunsignedintDATA_BLOCK_NUM=512; //数据块数量constunsignedintDINODE_START=4*BLOCK_SIZE; //inode起始位置constunsignedintDINODE_SIZE=512; //inode大小constunsignedintDINODE_NUM=32; //inode数量constunsignedintDATASTART=(2+DINODE_NUM)*BLOCK_SIZE; //数据区的开始地址constunsignedintACCOUNT_NUM=10; //用户数量/*inode结构体*/structinode{ unsignedshortdi_tag; /*inode标识*/ unsignedshortdi_number; /*关联文件数,当为0时表示删除文件,如一个目录至少包含两个文件:"."和".."*/ unsignedshortdi_mode; /*存取模式:0为目录,1为文件*/ unsignedshortdi_userID; /*当前inode所属用户0为根目录ID,一次下去是管理员目录、用户目录*/ unsignedshortdi_access; /*访问权限0为不允许普通用户访问(公共目录),1为允许普通用户访问*/ unsignedshortdi_size; /*文件大小,目录没有大小,值为0*/ unsignedshortdi_ctime;/*创建时间*/ unsignedshortdi_mtime;/*最后一次修改时间*/ unsignedshortdi_block[DATA_BLOCK_NUM];/*数据块块地址编号*/};/**超级块***/structsuper_block{ unsignedshorts_inodes_count;/*文件系统中inode的总数*/ unsignedshorts_blocks_count;/*数据块总数*/ unsignedshorts_r_blocks_count;/*保留块总数*/ unsignedshorts_free_blocks_count;//空闲块总数 unsignedshorts_free_inodes_count;/*空闲的inode总数*/ unsignedshorts_log_block_size;/*block的大小*/};/**账户信息**/structuser{ unsignedshortuser_id; //用户ID unsignedshortuser_access; //权限 stringusername; //用户名 stringpassword; //密码};/**文件/目录结构**/structdirectory{ stringname; /*目录名*/ unsignedshortd_ino; /*目录号*/};四、调试分析4.1运行环境 编译平台:MicrosoftVisualStudio2010 运行平台:win7/xp4.2调试分析五、缺点及改进5.1实验缺点 由于对Linux的文件系统理解不够深刻,导致程序在一些原理上的迷糊不清,而时间较短,因此采取了简化或者放开的方法。在写程序的开始,也没有做详细的规划,而且是四个人分工协作,因此在程序的结构上有些混乱。在后期做了一些调整,但是整体还是有缺陷的。另外,程序只是很简单的模拟了Linux的文件管理系统,只有一些非常简单的功能,而且功能考虑的也不尽全面、严谨,难免会出现一些Bug,另外,我们整体在写的时候是用的C++的写法,但是在编写的时候,又混用了c的一些方法,所以,整个程序更加混乱,给阅读理解带来非常大的困难。5.2实验改进 首先,我们先要把一些原理知识搞清楚,其次,做一个统一的项目规划,做好一些定义的声明,结构再清晰一些。更深层次的模拟Linux文件管理系统,将一些函数的考虑更加严谨、全面,多次调试,减少一些bug。尽量用规范的C++语言才编写,注清函数功能,便于相互分享调用阅读。六、实验总结 本实验是模拟Linux文件管理系统,而我们平时很少接触到Linux系统,只是在书上学了一些理论的皮毛,纸上得来总觉浅,因此在开始做的时候,感觉无从下手,只能去网上去查找一些相关知识,以及看老师给的例子,并且和其他组就行讨论,这个时间花了一天半的时间,但是成果不是很好,很多地方都不明白。但是时间紧迫,我们就边做边理解、讨论,这样造成一个非常大的困难,不知道从哪里下手,只能模仿着做,加深理解。在两天的仓促的时间里面,我们做出了一个简单可行的模拟文件系统,虽然问题不少,但是在时间的允许下,我们还是不错的。 在编程中,我们遇到了很多以前没有遇到的问题和知识,在通过相互讨论,上网查询等方法后,我们解决了大部分的问题,对C++语言的理解也加深了很多,对一个项目的需求也理解很多,一个合理的规划会提高不少效率。七、参考文献《C++程序设计》 清华大学出版社 谭浩强《算法与数据结构(第二版)》 高等教育出版社 张乃孝《操作系统教程(第四遍)》 高等教育出版社 孙钟秀 8.2源程序#include<iostream>#include<string>#include<stdio.h>usingnamespacestd;/*常变量*/constunsignedintBLOCK_SIZE=512; //块长constunsignedintDATA_BLOCK_NUM=512; //数据块数量constunsignedintDINODE_START=4*BLOCK_SIZE; //inode起始位置constunsignedintDINODE_SIZE=512; //inode大小constunsignedintDINODE_NUM=512; //inode数量constunsignedintDATA_START=(2+DINODE_NUM)*BLOCK_SIZE; //数据区的开始地址constunsignedintACCOUNT_NUM=10; //用户数量constunsignedintDIRECTORY_NUM=12; //每个目录最多允许拥有的子目录和文件constunsignedshortFILE_NAME_LENGTH=20; //最大文件名长度/**************************inode结构体**************************//*inode结构体*/structinode{ unsignedshortdi_tag; /*inode标识*/unsignedshortdi_number; /*关联文件数,当为0时表示删除文件,如一个目录至少包含两个文件:"."和".."*/ unsignedshortdi_mode; /*存取模式:0为目录,1为文件*/ unsignedshortdi_userID; /*当前inode所属用户0为根目录ID,一次下去是管理员目录、用户目录*/ unsignedshortdi_access; /*访问权限0为不允许普通用户访问(公共目录),1为允许普通用户访问*/ unsignedshortdi_size; /*文件大小,目录没有大小,值为0*/ unsignedshortdi_ctime;/*创建时间*/ unsignedshortdi_mtime;/*最后一次修改时间*/ unsignedshortdi_block;/*数据块块地址编号*/};/*———————————————————————— 超级块结构————————————————————————*/structsuper_block{ unsignedshorts_inodes_count;/*文件系统中inode的总数*/ unsignedshorts_free_inodes_count;/*空闲的inode总数*/ unsignedshorts_blocks_count;/*块总数*/ unsignedshorts_r_blocks_count;/*保留块总数*/ unsignedshorts_free_blocks_count;//空闲块总数 unsignedshorts_log_block_size;/*block的大小*/// unsignedshorts_free_blocks_group[GROUPNUM];//新增一个数组来记录每个数据块组中的空闲数据块计数// unsignedshorts_first_data_block;/*第一个数据block*/ // unsignedshorts_blocks_per_group;/*每blockgroup的block数量*/// unsignedshorts_inodes_per_group;/*每blockgroup的inode数量*/ };/*———————————————————————— 账户信息————————————————————————*/structuser{ unsignedshortuser_id; //用户ID unsignedshortuser_access; //权限1为管理员0为平民 stringusername; //用户名 stringpassword; //密码};/*———————————————————————— 文件、目录项结构————————————————————————*/structdirectory{ stringname; /*目录、文件名*/ stringcontent;/*文件数据,目录则没有数据*/ unsignedshortd_ino; /*目录、文件号*/};/*变量*/unsignedshortdi_bitmap[DINODE_NUM]; //硬盘inode节点位图1表示已使用0表示未使用unsignedshort bk_bitmap[DATA_BLOCK_NUM]; //数据块block位图structsuper_blocksuperBlock; //超级块structuseraccount[ACCOUNT_NUM]; //共创建ACCOUNT_NUM个账户FILE*f_stream; //文件指针structinode*cur_inode; //inode当前目录指针structinode*inode_temp; //inode临时指针 constchardiskName[30]="ext2forlinux.disk"; //模拟硬盘的文件名structdirectorydir_buf[DIRECTORY_NUM]; //目录数组,每个目录最多允许有12个项(子目录或者文件)stringcur_Path;//cmd的头表示所在哪个文件夹//inti_lock=0;//inode位图锁可能会多线程//intb_lock=0;//block位图锁structuser*cur_user; //当前用户structdirectorycur_dir[DIRECTORY_NUM];//当前目录/**********************函数声明********************/boolFormat(void); //此函数用于格式化boolinstall(void); //此函数用于装载虚拟硬盘的数据intFindFile(stringfilename);//次函数用于查找当前文件夹是否有该文件 boolaccess(structinode*pinode);//权限判断intmain(){ voidlogin(void); //此函数用于用户登陆 voidshowMenu(void);//此函数用于显示功能菜单 boolonAction(void);//此函数用于用户选择功能并执行 charformat_bool; /**************初始化************/ cout<<"系统已启动,是否初始化所有数据?\tY/N"<<endl; while(true){ cin>>format_bool; if(format_bool=='y'||format_bool=='Y'){ if(!Format())return0; break; } elseif(format_bool=='n'||format_bool=='N'){ cout<<"不初始化不能开始!"<<endl; continue; } else{ cout<<"请输入Y或者N"<<endl; continue; } } cout<<"初始化成功!"<<endl; /********转载虚拟硬盘数据***********/ if(!install()){ cout<<"加载失败,无效的硬盘格式"<<endl; //main(); return0; } elsecout<<"加载disk成功!"<<endl; cur_Path=cur_dir[1].name+"\\root"; /*******登陆**********/ login(); /**显示菜单**/ showMenu(); /**显示当前路径**/ cout<<cur_Path; while(onAction()); return0;}/*此函数用于格式化*/boolFormat(){ //创建文件 f_stream=fopen(diskName,"wb+"); if(f_stream==NULL){ cout<<"创建文件失败"<<endl; returnfalse; } //初始化超级块 superBlock.s_inodes_count=DINODE_NUM;/*文件系统中inode的总数*/ superBlock.s_free_inodes_count=DATA_BLOCK_NUM-2-ACCOUNT_NUM;/*空闲的inode总数初始化时,主目录和账户信息各占一块,10个用户10块*/ superBlock.s_blocks_count=DATA_BLOCK_NUM;/*块总数*/ superBlock.s_free_blocks_count=DATA_BLOCK_NUM-2-ACCOUNT_NUM;//空闲块总数主目录/10个用户/账户信息共占用12个 superBlock.s_log_block_size=BLOCK_SIZE;/*block的大小*/ //超级块放第1个物理块,第0个为引导 fseek(f_stream,BLOCK_SIZE,SEEK_SET); fwrite(&superBlock,BLOCK_SIZE,1,f_stream);// fprintf(f_stream,"thisissuperblock");//测试 //初始化dinode位图block位图 for(inti=0;i<DATA_BLOCK_NUM;i++){ if(i<2+ACCOUNT_NUM)bk_bitmap[i]=1; elsebk_bitmap[i]=0; } //初始化block位图 for(inti=0;i<DINODE_NUM;i++){ if(i<2+ACCOUNT_NUM)di_bitmap[i]=1; elsedi_bitmap[i]=0; } //位示图存放与第2.3块 fseek(f_stream,BLOCK_SIZE*2,SEEK_SET); fwrite(&di_bitmap,BLOCK_SIZE,1,f_stream);// fprintf(f_stream,"thisissuperblock");//测试 fseek(f_stream,BLOCK_SIZE*3,SEEK_SET); fwrite(&bk_bitmap,BLOCK_SIZE,1,f_stream);// fprintf(f_stream,"thisissuperblock");//测试 //初始化inode表 structinode*node_temp; node_temp=newinode; if(!node_temp) { printf("node_temp内存分配失败!"); returnfalse; } //主目录的inode node_temp->di_tag=0;//i节点标志 node_temp->di_number=2+ACCOUNT_NUM;//关联12个文件夹 node_temp->di_mode=0;//0为目录 node_temp->di_userID=0;//用户id第一个用户 node_temp->di_access=0;//0为公共可以访问 node_temp->di_size=0;//目录无size node_temp->di_ctime=0;/*创建时间*/ node_temp->di_mtime=0;/*修改时间*/ node_temp->di_block=0; fseek(f_stream,DINODE_START,SEEK_SET); fwrite(node_temp,sizeof(structinode),1,f_stream); //账户信息的inode node_temp->di_tag=1; node_temp->di_number=0;//无文件关联,此项等于0表明是账户信息,可用作区别于文件、目录的标识 node_temp->di_mode=0;//0为目录 node_temp->di_userID=0;//用户id第一个用户 node_temp->di_access=0;//0为公共可以访问 node_temp->di_size=0;//无size node_temp->di_ctime=0;/*创建时间*/ node_temp->di_mtime=0;/*修改时间*/ node_temp->di_block=1; /**账户信息存在数据块的第1块**/ fseek(f_stream,DINODE_START+BLOCK_SIZE,SEEK_SET); fwrite(node_temp,sizeof(structinode),1,f_stream); //管理员和9个普通用户的inode for(inti=1;i<=ACCOUNT_NUM;i++){ node_temp->di_tag=i+1;//inode标志 node_temp->di_number=2;//关联2个文件夹 node_temp->di_access=1;//1为用户私有 node_temp->di_mode=0;//0为目录 node_temp->di_userID=i;//用户id第一个用户 node_temp->di_size=0;//目录无size node_temp->di_ctime=0;/*创建时间*/ node_temp->di_mtime=0;/*修改时间*/ node_temp->di_block=i+1;//所占物理块号.从管理员到user9占用的位置为2~11. fseek(f_stream,DINODE_START+BLOCK_SIZE*(i+1),SEEK_SET); fwrite(node_temp,sizeof(structinode),1,f_stream); } /*******初始化主目录**********/ dir_buf[0].name="."; dir_buf[0].d_ino=0; dir_buf[1].name=".."; dir_buf[1].d_ino=0; dir_buf[2].name="admin"; dir_buf[2].d_ino=2;//管理员的inode号为2 //user1~user9的目录项 for(inti=0;i<ACCOUNT_NUM-1;i++){ dir_buf[i+3].name="user"+i; dir_buf[i+3].d_ino=i+3; } fseek(f_stream,DATA_START,SEEK_SET); fwrite(dir_buf,BLOCK_SIZE,1,f_stream); /**初始化账户信息**/ structuseraccount_temp[ACCOUNT_NUM]; //管理员账户 account_temp[0].username="admin"; account_temp[0].password="admin"; account_temp[0].user_access=1;//1为管理员 account_temp[0].user_id=2;//管理员目录的块号 //user1~user9 for(inti=1;i<ACCOUNT_NUM;i++){ account_temp[i].username="user"+i; account_temp[i].password="user"+i; account_temp[i].user_access=0; account_temp[i].user_id=i+2;//user[i]的物理块号 } fseek(f_stream,DATA_START+BLOCK_SIZE,SEEK_SET); fwrite(account_temp,BLOCK_SIZE,1,f_stream); /**初始化admin目录以及user1~user9**/ //清空dir_buf for(inti=0;i<DIRECTORY_NUM;i++){ dir_buf[i].d_ino=0; dir_buf[i].name="\0"; } for(inti=0;i<ACCOUNT_NUM;i++){ dir_buf[0].d_ino=2; dir_buf[0].name="."; dir_buf[1].d_ino=0; dir_buf[1].name=".."; fseek(f_stream,DATA_START+BLOCK_SIZE*(i+2),SEEK_SET);//管理员在第二块物理空间 } returntrue;}/*此函数用于装载虚拟硬盘的数据*/boolinstall(void){ /**函数声明**/ inode*getInode(unsignedint);//获取指定inode号的inode单元 boolgetDataBlock(unsignedint);//获取指定数据块号下的目录或文件 inti; cout<<"installing..."<<endl; f_stream=fopen(diskName,"rb+");//只读方式打开硬盘模拟文件 if(f_stream==NULL) { cout<<"文件打开失败"<<endl; return0; } //读超级块 fseek(f_stream,BLOCK_SIZE,SEEK_SET); fread(&superBlock,sizeof(structsuper_block),1,f_stream); ////// cout<<"加载超级块:"<<superBlock.s_blocks_count<<endl; inode_temp=newinode; if(!inode_temp) { cout<<"cur_inode内存分配失败!"<<endl; return0; } cur_inode=newinode; if(!cur_inode) { cout<<"cur_inode内存分配失败!"<<endl; return0; } //读取inode位示图 fseek(f_stream,BLOCK_SIZE*2,SEEK_SET); fread(di_bitmap,BLOCK_SIZE,1,f_stream); cout<<"加载inode位示图:"<<di_bitmap[0]<<endl; //读取block位示图 fseek(f_stream,BLOCK_SIZE*3,SEEK_SET); fread(bk_bitmap,BLOCK_SIZE,1,f_stream); cout<<"加载block位示图:"<<bk_bitmap[0]<<endl; //读取账户信息的inode inode_temp=getInode(1); if(inode_temp==NULL) { cout<<"加载账户信息失败!"<<endl; returnfalse; } //changeinode();//交换指针后cur_inode指向当前目录的inode //读取账户信息 cout<<"账户信息块号:"<<inode_temp->di_block<<endl; fseek(f_stream,DATA_START+BLOCK_SIZE*inode_temp->di_block,SEEK_SET); fread(account,BLOCK_SIZE,1,f_stream); cout<<"加载账户信息:"<<account[0].username<<'\t'<<account[0].password<<endl; for(i=0;i<ACCOUNT_NUM;i++) { if(account[i].user_id!=0) { cout<<account[i].username<<account[i].password; } } cur_inode=getInode(0);//读取主目录的inode当前inode指向主目录的inode if(cur_inode->di_mode!=0) { cout<<"读取主目录失败,请重新格式化!"<<endl; } else { //将主目录读入cur_dir数组 getDataBlock(cur_inode->di_block); } returntrue;}/*此函数用于用户登陆*/voidlogin(){ }/*此函数用于显示功能菜单*/voidshowMenu(void){ cout<<"help\t\t显示命令帮助\n"; cout<<"create[文件名]\t创建文本文件\n"; cout<<"cdir[目录名]\t创建文件夹\n"; cout<<"read[文件名]\t读取一个文件\n"; cout<<"edit[文件名]\t编辑一个文件\n"; cout<<"cd[目录名]\t进入子目录或者上级目录\n"; cout<<"attr[文件名]\t显示该文件的属性\n"; cout<<"del[文件名]\t删除文件\n"; cout<<"dir\t\t显示当前目录下的文件和文件夹\n"; cout<<"rename[文件名]\t重命名\n"; cout<<"logout\t\t注销\n"; cout<<"exit\t\t退出系统\n";}/**此函数用于用户选择功能并执行**/boolonAction(){ voidshowMenu(); voidshowDir(); voidlogout(); voidcreateFile(stringstr);//创建一个文件 voidcreateDir(stringstr); voideditFile(stringstr); voidvisit(stringstr); voidattrib(stringstr); voidDelete(stringstr);//删除一个文件 voidrename(stringstr); boolread(stringfilename);//此函数用于读取一个文件 inode*getInode(unsignedint); fflush(stdin); while(true){ fflush(stdin); charstr[20];//用户输入的命令 charname[20];//文件或者目录名 stringnamestr; cin>>str; // cout<<"str="<<str<<endl; // cout<<"测试:"<<str.find_first_of("create",0)<<'\t'<<str.find_first_of("",0)<<'\t'<<endl; if(strcmp(str,"exit")==0){ fclose(f_stream); returnfalse; } elseif(strcmp(str,"dir")==0){ showDir();//显示当前文件夹下的所有文件和文件夹 } elseif(strcmp(str,"help")==0){ showMenu(); //显示功能菜单 } elseif(strcmp(str,"logout")==0){ logout();//注销 } elseif(strcmp(str,"create")==0){ cin>>namestr; createFile(namestr); } elseif(strcmp(str,"cdir")==0){ cin>>namestr; createDir(namestr);//创建文件夹 } elseif(strcmp(str,"read")==0){ cin>>name; read(name);//读文件 } elseif(strcmp(str,"edit")==0){ cin>>name; editFile(name);//编辑文件 } elseif(strcmp(str,"cd")==0){ cin>>name; visit(name);//目录访问 } elseif(strcmp(str,"attr")==0){ cin>>name; attrib(name);//显示该文件的属性 } elseif(strcmp(str,"del")==0){ cin>>name; Delete(name);//删除文件 } elseif(strcmp(str,"rename")==0){ cin>>name; rename(name);//重命名 } /**测试**/ elseif(strcmp(str,"getInode")==0){ inti; cin>>i; getInode(i);//查看inode } /*****/ elsecout<<str<<"不是内部命令!"<<endl; }}/**此函数用于显示当前目录下所有文件和文件夹信息**/voidshowDir(void){ cout<<"thisisshowDir"<<endl;}/**此函数用于注销用户**/voidlogout(void){ cout<<"thisislogout"<<endl;}/**此函数用于创建文件夹**/voidcloseFile(stringstr){ cout<<"thisiscloseFile"<<endl;}/**此函数用于编辑文件**/voideditFile(stringstr){ cout<<"thisiseditFile"<<endl;}/**访问目录**/voidvisit(stringstr){ cout<<"thisisvisit"<<endl;}/**显示文件属性**/voidattrib(stringstr){ cout<<"thisisattrib"<<endl;}/**文件或者目录重命名**/voidrename(stringstr){ cout<<"thisisrename"<<endl;}/**此函数判断对要访问的文件夹是否有访问权限**/boolaccess(structinode*pinode)//调用的时候要把当前文件的inode指针传送过来这里0表示普通用户1表示管理员{ if(pinode->di_userID==cur_user->user_id)returntrue;//该文件是当前用户拥有 if(cur_user->user_access==1)returntrue;//该用户为管理员 returnfalse;}/**此函数用于读取相应inode号下面的inode块**/structinode*getInode(unsignedintn){ inode*temp; temp=newinode; fseek(f_stream,DINODE_START+BLOCK_SIZE*n,SEEK_SET); fread(temp,sizeof(structinode),1,f_stream);// cout<<"inode:\n"<<"di_tag:"<<temp->di_tag<<"\tdi_number:"<<temp->di_number<<"\tdi_mode:"<<temp->di_mode<<"\tdi_userID:"<<temp->di_userID<<"\ndi_block:"<<temp->di_block<<endl; returntemp; }/**此函数将指定编号下的数据块的目录或者文件读入cur_dir**/boolgetDataBlock(unsignedintn){ //directory*temp; //temp=newdirectory; fseek(f_stream,DATA_START+BLOCK_SIZE*n,SEEK_SET); fread(cur_dir,sizeof(structdirectory)*cur_inode->di_number,1,f_stream);// cout<<"getDataBlock函数:"<<cur_dir[0].name<<'\t'<<cur_dir[0].d_ino<<endl; returntrue;}/**此函数用于判断当前文件夹有没有查找的文件没有返回-1有返回该文件的inod号**/intFindFile(stringfilename){ inti; if(filename.length()>FILE_NAME_LENGTH){ cout<<"您输入的文件名长度大于14,文件查找失败!"<<endl;return-1;}if(filename==".") { cout<<"自身文件夹不允许操作!"<<endl; return-1;} if(".."==filename) { cout<<"父目录不允许操作!"<<endl; return-1;}for(i=0;i<cur_inode->di_number;i++){ if(dir_buf[i].name==filename) { cout<<"当前文件存在!"<<endl; returndir_buf[i].d_ino; }} cout<<"未找到此文件"<<endl; return-1;}/**此函数由于读取一个文件,将文件内容输出**/boolread(stringfilename){ structinode*temp; if(FindFile(filename)==-1) { returnfalse; } temp=getInode(FindFile(filename)); if(!access(temp)) { cout<<"您没有此文件的访问权限"<<endl; returnfalse; } if(temp->di_mode!=1) { cout<<filename<<"不是一个文件"<<endl; returnfalse; } char*buf; buf=(char*)malloc(BLOCK_SIZE*(temp->di_size/BLOCK_SIZE+1)); fseek(f_stream,DATA_START+BLOCK_SIZE*temp->di_block,SEEK_SET); fread(buf,BLOCK_SIZE*(temp->di_size/BLOCK_SIZE+1),1,f_stream); returntrue;}voidcreateFile(stringstr){ inti,j,m,file_access;if(str.length()>FILE_NAME_LENGTH){ cout<<"您输入的文件名长度大于20,文件创建失败!";return;}if(FindFile(str)!=-1){ cout<<"您输入的文件名已存在,文件名不能重复,创建失败!"<<endl; return;}if(superBlock.s_free_inodes_count==0||superBlock.s_free_blocks_count==0){ cout<<"当前存储空间已满!请删除一些文件后再存储。"<<endl; return;}cout<<"请输入文件的访问权限。1表示共享文件,0表示私有文件:"<<endl;cin>>file_access;fflush(stdin);for(j=0;j<DINODE_NUM;j++){ if(di_bitmap[j]==0) { di_bitmap[j]=1; break; }}for(m=0;m<DATA_BLOCK_NUM;m++){ if(bk_bitmap[m]==0) { bk_bitmap[m]=1; break; } }char*buf;intk=0,tag=0;buf=(char*)malloc(BLOCK_SIZE*sizeof(char));cout<<"请输入文件的内容,以“###”结束!"<<endl;for(i=0;i<BLOCK_SIZE;i++){ buf[i]=getchar();if(tag==0)k=0;if(buf[i]=='#') { tag=1; k++; if(k==3) break; } else { k=0; tag=0;}}buf[i-2]='\0';cout<<"文件长度为:"<<strlen(buf);structinode*node_temp; node_temp=newinode; if(!node_temp) { cout<<"node_temp内存分配失败!文件创建不成功!"<<endl; return; }node_temp->di_tag=j;node_temp->di_number=1; /*关联文件数,当为0时表示删除文件,如一个目录至少包含两个文件:"."和".."*/node_temp->di_mode=1; /*存取模式:0为目录,1为文件*/node_temp->di_userID=cur_user->user_id; /*当前inode所属用户0为根目录ID,一次下去是管理员目录、用户目录*/node_temp->di_access=file_access; /*访问权限0为不允许普通用户访问(公共目录),1为允许普通用户访问*/node_temp->di_size=strlen(buf); /*文件大小,目录没有大小,值为0*/node_temp->di_ctime;/*创建时间*/node_temp->di_mtime;/*最后一次修改时间*/node_temp->di_block=m;/*数据块块地址编号*/ fseek(f_stream,DINODE_START+j*BLOCK_SIZE,SEEK_SET);fwrite(node_temp,BLOCK_SIZE,1,f_stream);//将新建文件inode写入磁盘fseek(f_stream,DATA_START+m*BLOCK_SIZE,SEEK_SET);fwrite(buf,BLOCK_SIZE,1,f_stream);//将新建文件的内容写入磁盘dir_buf[cur_inode->di_number].d_ino=j;//修改当前目录的结构dir_buf[cur_inode->di_number].name=str; fseek(f_stream,DATA_START+BLOCK_SIZE*cur_inode->di_block,SEEK_SET);//将当前目录信息写入文件的block区fwrite(dir_buf,BLOCK_SIZE,1,f_stream);cur_inode->di_number++;//当前目录关联文件数++superBlock.s_free_inodes_count--;//超级块中空闲的inode数目减一superBlock.s_free_blocks_count--;//超级块中空闲的block数目减一fseek(f_stream,BLOCK_SIZE,SEEK_SET);//修改超级块fwrite(&superBlock,BLOCK_SIZE,1,f_stream);fseek(f_stream,2*BLOCK_SIZE,SEEK_SET);//fwrite(di_bitmap,BLOCK_SIZE,1,f_stream);fwrite(bk_bitmap,BLOCK_SIZE,1,f_stream);cout<<"文件已成功添加"<<endl;free(buf);return;}voidDelete(stringstr){ inti,j,m; intnumb;//numb用来存储需要删除的文件inode号charC;if(str.length()>FILE_NAME_LENGTH)//判断输入的文件名是否超过长度{ cout<<"您输入的文件名长度大于20,操作失败!";return;}numb=FindFile(str);//判断是否存在该文件或文件夹if(numb==-1){ cout<<"该文件或文件夹不存在!"<<endl; return;}if(!access(getInode(numb)))//判断是否有权限删除文件 { cout<<"您没有权限删除该文件或文件夹!"<<endl; return; }structinode*node_temp;//node_temp指向需要删除文件inode结构体node_temp=getInode(numb);if(node_temp->di_mode==1)//如果是文件的话就直接删除{ di_bitmap[numb]=0;//将文件inode释放,即将相应位示图位置置为0bk_bitmap[node_temp->di_block]=0;//将文件block释放,即将相应位示图位置置为0cur_inode->di_number--;//当前文件夹关联文件减一for(i=0;i<node_temp->di_number;i++)//改变当前文件夹的关联文件 { if(dir_buf[i].name==str) break; } for(j=i;j<node_temp->di_number-1;j++){ dir_buf[j]=dir_buf[j+1];}fseek(f_stream,DATA_START+BLOCK_SIZE*cur_inode->di_block,SEEK_SET);//将当前目录信息写入文件的block区fwrite(dir_buf,BLOCK_SIZE,1,f_stream);fseek(f_stream,2*BLOCK_SIZE,SEEK_SET);//修改位示图fwrite(di_bitmap,BLOCK_SIZE,1,f_stream);fseek(f_stream,3*BLOCK_SIZE,SEEK_SET);fwrite(bk_bitmap,BLOCK_SIZE,1,f_stream);superBlock.s_free_inodes_count--;//超级块中空闲的inode数目加一superBlock.s_free_blocks_count--;//超级块中空闲的block数目加一fseek(f_stream,BLOCK_SIZE,SEEK_SET);//修改超级块fwrite(&superBlock,BLOCK_SIZE,1,f_stream); }elseif(node_temp->di_mode==0)//是文件夹的话则判断该文件夹中是否有文件{ if(node_temp->di_number>2)//如果有文件则不能删除 { cout<<"当前文件夹内包含文件,不允许被删除!"<<endl; return; }cout<<"是否真的要删除该文件夹?(Y/N)";//若没有文件则判断是否要删除该文件夹cin>>C;if(C=='N'||C=='n')return;elseif(C=='Y'||C=='y'){ di_bitmap[numb]=0;bk_bitmap[node_temp->di_block]=0;cur_inode->di_number--; for(i=0;i<node_temp->di_number;i++) { if(dir_buf[i].name==str) break; } for(j=i;j<node_temp->di_number-1;j++){ dir_buf[j]=dir_buf[j+1];}fseek(f_stream,DATA_START+BLOCK_SIZE*cur_inode->di_block,SEEK_SET);//将当前目录信息写入文件的block区fwrite(dir_buf,BLOCK_SIZE,1,f_stream);fseek(f_stream,2*BLOCK_SIZE,SEEK_SET);//修改位示图fw

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论