当前位置:文档之家› 文件系统课程设计报告

文件系统课程设计报告

操作系统课程设计报告题目:文件系统专业:软件工程院系:信息管理学院年级:大三软件Q1141学号: ******** *名:**指导教师:***职称:副教授湖北经济学院教务处制目录操作系统课程设计报告一实验内容 (2)二设计的基本概念和原理 (2)三总体设计 (2)2-1 文件的组织结构............................................................. (2)2-2 磁盘空间的管理............................................................. (2)2-3 目录结构 (3)2-4文件操作 (4)四详细设计 (4)4-1 建立文件(create_file)流程图 (4)4-2 打开文件(open_file)流程图 (6)4-3读文件(read_file)流程图 (7)4-4 写文件(write_file)流程图 (8)4-5 关闭文件(close_file)流程图 (9)4-6 删除文件(delete_file)流程图 (10)4-7 显示文件内容(typefile)流程图 (11)4-8 建立目录(md)流程图 (12)4-9显示目录内容流程图 (13)五详细代码 (14)六运行结果截图 (40)七总结 (44)八参考文献 (45)一、实验内容要求设计一个简单的文件系统,用文件模拟磁盘,实现以下功能:(1)支持多级目录结构;(2)实现的命令包括建立目录、列目录、删除空目录、建立文件、删除文件、显示文件内容、打开文件、读文件、写文件、关闭文件、改变文件属性。

(3)编写主函数对所有操作进行测试二、设计的基本概念和原理为了正确地实现文件的存取,文件系统设计了一组与存取文件有关的功能模块,用户可以用“访问指令”调用这些功能模块,以实现文件的存取要求。

我们把文件系统设计的这一组功能模块称为“文件操作“,实验就是要模拟实现一些文件操作。

文件操作不是独立的,它和文件系统的其他部分密切相关,若要实现文件操作就离不开文件的目录结构、文件的组织结构和磁盘空间的管理。

因此,这个实习虽然是文件操作的模拟实现,但还是必须模拟一部分文件的组织结构、目录结构和磁盘空四、详细设计(1)建立文件:create_file(文件名,文件属性)(4)写文件write_file(文件名,缓冲,写长度)(8)目录操作命令:建立目录(md)五、详细代码int sopen(char *name) //在已打开的文件表中查找文件name{int i;i = 0;while(i<openfile.length && strcmp(openfile.file[i].name, name) !=0)//依次查找已打开文件表{i++;}if(i>=openfile.length){return -1;}return i;}void dopen(char *name) //在已打开文件表中删除文件name{int i;i = sopen(name);if(i==-1){printf("文件未打开\n");}else{copy(&openfile.file[i], &openfile.file[openfile.length - 1]);openfile.length--;}}int iopen(ofile *x)//向已打开文件列表中插入文件x->name{int i;i = sopen(x->name);if(i!=-1){printf("文件已经打开\n");return false;}else if(openfile.length == n){printf("已打开文件表已满");return false;}else{copy(&openfile.file[openfile.length], x);openfile.length ++;return true;}}int allocate()//分配一个磁盘块,返回块号{int i;fseek(fc, 0, SEEK_SET);//将模拟磁盘的文件指针移至模拟磁盘FAT表fread(buffer1,64L, 1, fc);for(i = 3; i < 63; i++){if(buffer1[i] == 0)//FAT中的第i项为0,分配第i块磁盘块,修改FAT 表,并且写回磁盘{buffer1[i] = 255;fseek(fc, 0, SEEK_SET);fwrite(buffer1, 64L, 1, fc);return i; //返回磁盘号}}fread(buffer1, 64L, 1, fc);//将FAT表中第二个磁盘块读入模拟缓冲buffer1for(i = 0; i < 63; i++)if(buffer1[i] == 0)//AT中的第i项为0,分配第i+64块磁盘块,修改FAT表,并且写回磁盘{buffer1[i] = 255;fseek(fc, -64L, SEEK_CUR);fwrite(buffer1, 64L, 1, fc);return i + 64; //返回磁盘号}}printf("已经没有磁盘空间\n");return false;}int read_file(char *name, int length)//读取文件,文件名为name, 读取长度为length{int i, t;char ch;if((i=sopen(name)) == -1){printf("文件未打开或不存在\n");return false;}if(openfile.file[i].flag == 1)printf("文件以写方式打开,不能读\n");return false;}t = 0;fseek(fc, openfile.file[i].read.dnum * 64L, SEEK_SET);fread(buffer1, 64, 1, fc);while(t < length && buffer1[openfile.file[i].read.bnum] != '#'){putchar(buffer1[openfile.file[i].read.bnum]); //读出一个字符显示在屏幕上if((t+1)%64 ==0){putchar('\n');}openfile.file[i].read.bnum ++;//修改读指针if(openfile.file[i].read.bnum >= 64) //一块读完,读取下一块{fseek(fc,openfile.file[i].read.dnum/64*64, SEEK_SET);fread(buffer1, 64, 1, fc);openfile.file[i].read.dnum=buffer1[openfile.file[i].read.dnum%64];openfile.file[i].read.bnum = 0; //修改读指针fseek(fc, openfile.file[i].read.dnum *64L, SEEK_SET);fread(buffer1, 64, 1, fc);}t++;}}int write_file(char *name, char *buff, int length)//name 文件路径名//buff 存放准备写入磁盘的内容//length 写入内容的长度{int i, t, dd;if((i=sopen(name))== -1){printf("文件未打开或不存在\n");return false;}if(openfile.file[i].flag == 0){printf("文件以只读方式打开,不能写\n");return false;}t = 0;fseek(fc,openfile.file[i].write.dnum*64L, SEEK_SET);fread(buffer1,64,1,fc);while(t<length){buffer1[openfile.file[i].write.bnum]=buff[t];openfile.file[i].write.bnum++;openfile.file[i].length++;if(openfile.file[i].write.bnum>=64){fseek(fc, openfile.file[i].write.dnum*64L, SEEK_SET);fwrite(buffer1,64,1,fc);/*一块写完,写回磁盘*/if((dd=allocate())==false){openfile.file[i].write.bnum--;openfile.file[i].length--;printf("无磁盘空间,部分信息丢失,写失败\n");return (false);}fseek(fc,openfile.file[i].write.dnum/64*64L, SEEK_SET);fread(buffer1,64,1,fc);buffer1[openfile.file[i].write.dnum%64]=dd;fseek(fc,openfile.file[i].write.dnum/64*64L, SEEK_SET); fwrite(buffer1,64,1,fc);openfile.file[i].write.dnum=dd;openfile.file[i].write.bnum=0;}t++;}fseek(fc, openfile.file[i].write.dnum*64L, SEEK_SET);fwrite(buffer1,64,1,fc);//一块写完,写回磁盘//}/*写函数结束*/int search(char *name, int flag, int *dnum, int *bnum)//查找路径名为name的文件或目录,返回该目录的起始盘块号//flag=8 表示查找目录,否则为文件//dnum, bnum 返回文件或目录的目录项登记位置,盘块dnum中第bnum项{int k, i, s, t, j, last = 0;char pna[3], type[2];if(strcmp(name, "") == 0 || strcmp(name, "/") == 0)//根目录return 2;k = 0;if(name[0] == '/') k =1;i = 2; // i为根目录的起始盘号while(last != 1) //pna为从name中分离出"/"后一个目录名或文件名{for(s = 0; name[k]!='.' && name[k] != '/' && s < 3 && name[k]!= '\0'; s++, k++)pna[s] = name[k];for( ; s < 3; s++)//用空格补齐全名字长度pna[s] = ' ';while(name[k]!='.' && name[k]!='\0' && name[k] != '/')//除去多余字符k++;type[0]= type[1] = ' ';if(name[k] == '.')// 取文件类型名if(flag == 8){printf("目录不应该有类型名,查找失败\n");return false;}else{//文件遇到类型名认为结束,后面的字符作废k++;if(name[k] != '\0') type[0] = name[k];k++;if(name[k] != '\0') type[1] = name[k];if(name[k] != '\0' && name[k+1] != '\0'){printf("文件名错误\n");return false;}last = 1;}elseif(name[k] != '\0') k ++;if(name[k] == '\0')last = 1;//查找名字等于pna的目录项fseek(fc, i*64L, SEEK_SET);fread(buffer2, 64L, 1, fc);j = 0;if(last ==1 && flag != 8) //查找名字pna,类型名type的文件目录项while(j < 8 && !buffer2[j].attribute != 8 && buffer2[j].name[0] == pna[0] && buffer2[j].name[1]== pna[1] && buffer2[j].name[2] == pna[2])j ++;elsewhile(j < 8 && !buffer2[j].attribute == 8 &&buffer2[j].name[0] == pna[0] && buffer2[j].name[1]== pna[1] &&buffer2[j].name[2] == pna[2])j ++;if(j < 8) //找到该目录或文件if(last == 1) //查找结束{*dnum = i;*bnum = j;return buffer2[j].address;}else{i = buffer2[j].address;}else{printf("路径错误\n");return false;}}//while 查找结束}//search查找结束int create_file(char *name, int attribute)//建立文件,路径为name,文件属性attribute{int dnum, bnum, i, j, last, k, s, d, t, tt, b, dd, flag, dn, bn;char dname[3], tname[2], pathname[20];ofile x;if(attribute % 2 == 1){printf("只读文件,无法写,不能建立\n");return false;}if(openfile.length == n){printf("已打开表已满,不能建立\n");return false;}//将name分为两部分,目录路径pathname和目录名dnamefor(j = 0; name[j] != '\0'; j++)//查找最后一个'/'{if(name[j] == '/') s = j;}for(j = 0; j < s; j++)//分离目录路径{pathname[j] = name[j];}pathname[j] = '\0'; //字符数组最后一个置\0for(k = 0, j = s+1; name[j]!='\0' && k < 3 && name[j]!='.'; j++,k++)//分离文件名{dname[k] = name[j];}if(k == 0){printf("文件名错误或目录名错误\n");return false;}for(; k < 3; k++){dname[k] = ' ';}k = 0;if(name[j ++] == '.')//分离类型名{for( ; name[j] != '\0' && k < 2 && name[j] != '.'; j++, k++)tname[k] = name[j];}for( ; k < 2; k ++)tname[k] = ' ';if((d = search(pathname, 8, &dn, &bn)) == false)//找目录路径{printf("目录不存在,不能建立\n");return false;}//确认该目录不存在的同时查找空目录项b = -1;fseek(fc, d*64L, SEEK_SET);fread(buffer2, 64L, 1, fc); //读出D盘块的内容for(t = 0; t < 8; t ++){if(buffer2[t].name[0] == dname[0] && buffer2[t].name[1] == dname[1] && buffer2[t].name[2] == dname[2] && buffer2[t].type[1] == tname[1]){//找到名字dname的文件,建立失败printf("文件已经存在,不能建立\n");return false;}if(buffer2[t].name[0] == '$' && b == -1)b = t;}if(b == -1)//没有空目录,建立失败{printf("目录无空间\n");return false;}if((dd = allocate()) == false) //分配给建立目录的磁盘盘块dd {printf("建立文件失败\n");return false;}//填写项目for(i = 0; i < 3; i++){buffer2[b].name[i] = dname[i];}for(i = 0; i < 2; i ++){buffer2[b].type[i] = tname[i];}buffer2[b].attribute = attribute;buffer2[b].address = dd;buffer2[b].length = 0;fseek(fc, d * 64L, SEEK_SET);fwrite(buffer2, 64L, 1, fc);// 填写已打开文件表strcpy(, name);x.attribute = attribute;x.number = dd;x.length = 0;x.flag = 1;x.read.dnum = x.write.dnum = dd;x.read.bnum = x.write.bnum = 0;iopen(&x);}//文件建立结束int open_file(char *name, int attribute)//打开文件{ofile x;int dnum, bnum, last, i, d;if( (d=search(name, 4, &dnum, &bnum)) == false) {printf("文件不存在,打开文件失败\n");return false;}fseek(fc, dnum * 64L, SEEK_SET);fread(buffer2, 64, 1, fc);if((buffer2[bnum].attribute%2 == 1) && attribute == 1) //对只读文件要求写{printf("文件不能写, 打开失败");return false;}strcpy(, name);x.attribute = buffer2[bnum].attribute;x.number = buffer2[bnum].address;x.read.dnum = x.write.dnum = buffer2[bnum].address;x.read.bnum = x.write.bnum = 0;x.flag = attribute;if(attribute == 1){while(d != '\xff') //寻找文件末尾{fseek(fc, d/64*64L, SEEK_SET);fread(buffer1, 64L, 1, fc); //读出dnum项所在FATlast = d;d = buffer1[d % 64];}x.write.dnum = last;fseek(fc, last*64L, SEEK_SET);for(i = 0; i < 64 && buffer1[i] != '#'; i++);x.write.bnum = i;x.length = (buffer2[bnum].length - 1) * 64 + i;}iopen(&x);}int close_file(char *name)//关闭文件{int i, dnum, bnum;if((i = sopen(name)) == -1){printf("打开的文件中没有改文件,关闭失败\n");return false;}if(openfile.file[i].flag == 1) //写文件的追加文件的结束符{fseek(fc, openfile.file[i].write.dnum * 64L, SEEK_SET);fread(buffer1, 64, 1, fc);buffer1[openfile.file[i].write.bnum] = '#';fseek(fc, openfile.file[i].write.dnum * 64L, SEEK_SET);fwrite(buffer1, 64, 1, fc);fputc('#', fc);search(name, 4, &dnum, &bnum);//查找文件目录位置//修改目录中文件长度fseek(fc, dnum*64L, SEEK_SET);fread(buffer2, 64, 1, fc);buffer2[bnum].length = openfile.file[i].length/64+1;fseek(fc, dnum*64L, SEEK_SET);fwrite(buffer2, 64, 1, fc);}//在已打开的文件表中删除该文件的登记项if(openfile.length > 1){copy(&openfile.file[i], &openfile.file[openfile.length - 1]);openfile.length --;}}int delete_doc(char *name)//删除文件{int dnum, bnum, t;if((t = search(name, 4, &dnum, &bnum)) == false) //查找文件{printf("文件不存在\n");return false;}if(sopen(name) != -1) //文件已打开,不能删除{printf("文件已打开,不能删除\n");return false;}fseek(fc, dnum * 64L, SEEK_SET);fread(buffer2, 64, 1, fc);buffer2[bnum].name[0] = '$'; //将该文件的目录置成空目录fseek(fc, dnum * 64L, SEEK_SET);fwrite(buffer2, 64, 1, fc);while(t != '\xff'){dnum = t;fseek(fc, dnum/64*64, SEEK_SET);fread(buffer1, 64, 1, fc);t = buffer1[dnum % 64];buffer1[dnum % 64] = 0;fseek(fc, dnum/64*64L, SEEK_SET);fwrite(buffer1, 64, 1, fc);}}//文件删除结束int md(char *name)//建立目录,目录路径为name{int dnum, bnum, i, j, last, k, s, d, t, tt, b, dd, flag, dn, bn;char dname[3], pathname[20];i = 2; //i等于根目录的起始盘块号//将name分成两部分,目录路径path和目录名dnamefor(j = 0; name[j] != '\0'; j++) //查找最后一个'/'{if(name[j] == '/') s = j;}//分离目录路径for(j = 0; j < s; j++){pathname[j] = name[j];}pathname[j] = '\0';//分离目录名for(k = 0, j = s+1; name[j] != '\0' && k < 3 && name[j] !='.'; j++, k++) dname[k] = name[j];if(k == 0 ){printf("错误文件名或目录名\n");return false;}for(; k < 3; k++){dname[k] = ' ';}if((d = search(pathname, 8, &dn, &bn)) == false)//找不到目录路径{printf("目录不存在,不能建立\n");return false;}b = -1;//确认该目录存在的同时查找空目录项fseek(fc, d*64L, SEEK_SET);fread(buffer2, 64L, 1, fc); //读出D盘块内容for(t =0; t < 8; t ++){if(buffer2[t].name[0] == dname[0] && buffer2[t].name[1] == dname[1] && buffer2[t].name[2] == dname[2] && buffer2[t].attribute == 8){//找到名字dname的目录,建立失败printf("目录已经存在,不能建立\n");return false;}if(buffer2[t].name[0] == '$' && b== -1)b = t;}if(b == -1) //没有空目录项,不能建立{printf("目录无空间\n");return false;}if((dd = allocate()) == false){printf("没有磁盘空间\n");//分配给建立目录的磁盘盘块dd return false;}//填写目录项for(i = 0; i < 3; i++){buffer2[b].name[i] = dname[i];}buffer2[b].type[0] = buffer2[b].type[1] = ' ';buffer2[b].attribute = 8;buffer2[b].address = dd;buffer2[b].length = 0;fseek(fc, d * 64L, SEEK_SET);fwrite(buffer2, 64L, 1, fc);//分给新建目录的盘块初始化for(t = 0; t < 0; t ++)buffer2[t].name[0] = '$';fseek(fc, dd*64L, SEEK_SET);fwrite(buffer2, 64L, 1, fc);}//建立目录结束int dis_dir(char *name)//显示目录内容{int i, bnum, t, tt, dnum, dn, bn;if((dnum = search(name, 8, &dn, &bn)) == false)//找不到目录路径{printf("目录不存在\n");return false;}printf("名称\t 扩展名\t 起始盘块\t 长度\n");//显示目录类容fseek(fc, dnum*64L, SEEK_SET);fread(buffer2, 64L, 1, fc);for(t = 0; t < 8; t ++){if(buffer2[t].name[0] != '$')printf("%c%c%c\t%c%c\t%4d%7d\n",buffer2[t].name[0], buffer2[t].name[1], buffer2[t].name[2], buffer2[t].type[0],buffer2[t].type[1], buffer2[t].address, buffer2[t].length);}}//显示目录函数结束int rd(char *name)//删除空目录{int dnum, bnum, t, i, flag;if((t = search(name, 8, &dnum, &bnum)) == false)//查找文件{printf("目录不存在\n");return false;}if(strcmp(name,"/") == 0)//根目录不能删除{printf("该目录为根目录,不能删除\n");return false;}fseek(fc, t * 64L, SEEK_SET);fread(buffer2, 64, 1, fc);flag = 1;for(i = 0; i < 8; i ++){if(buffer2[bnum].name[0] != '$')flag = 0;}if(flag == 0){printf("该目录为非空目录,不能删除\n");return false;}fseek(fc, dnum * 64L, SEEK_SET);fread(buffer2, 64, 1, fc);buffer2[bnum].name[0] = '$';fseek(fc, dnum * 64L, SEEK_SET);fwrite(buffer2, 64, 1, fc);fseek(fc, t/64*64, SEEK_SET);fread(buffer1, 64, 1, fc);t = buffer1[t%64];buffer1[t%64] = 0;fseek(fc, t/64*64, SEEK_SET);fwrite(buffer1, 64, 1, fc);}int typefile(char *name)//显示文件内容{int i, dnum, dn, bn, t;if((dnum = search(name, 1, &dn, &bn)) == false) {printf("文件不存在\n");return false;}if(sopen(name) != -1){printf("该文件打开,不能显示\n");return false;}while(dnum != '\xff'){fseek(fc, dnum * 64L, SEEK_SET);fread(buffer1, 64, 1, fc); //读一个盘块到缓冲区for(t = 0; t < 64 && buffer1[t] != '#'; t++) //显示缓冲内容putchar(buffer1[t]);printf("\n");}//获得下一个盘块fseek(fc, dnum/64*64L, SEEK_SET);fread(buffer1, 64, 1, fc);dnum = buffer1[dnum % 64];}//显示文件函数结束int change(char *name, int attribute)//改变文件的属性为attribute {int dnum, bnum;if(search(name, 1, &dnum, &bnum) == false){printf("文件不存在\n");return false;}if(sopen(name) != -1){printf("该文件打开,不能改变文件属性\n");return false;}fseek(fc, dnum*64L, SEEK_SET);fread(buffer2, 64, 1, fc); //读出该目录所在盘块 buffer2[bnum].attribute = attribute;//修改属性 fseek(fc, dnum * 64L, SEEK_SET);fwrite(buffer2, 64, 1, fc); //写回磁盘}//改变文件属性结束六、实验主界面及运行截图1.建立目录2.显示目录内容3.建立文件4.打开文件5.写文件6显示目录内容7.关闭文件七、总结文件这一块内容从大一开始c语言这一块就开始学了,但基础一直没打好,借着这次课程设计的机会,我打算复习文件操作。

相关主题