版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、 文件管理系统模拟1.实验目的通过一个简单多用户文件系统的设计,加深理解文件系统的内部功能及内部实现2.实验内容为Linux系统设计一个简单的二级文件系统。要求做到以下几点:1可以实现以下几条命令至少4条login用户登录dir列文件目录create创立文件delete删除文件open翻开文件close关闭文件read读文件write写文件2列目录时要列出文件名、物理地址、保护码和文件长度;3源文件可以进行读写保护。3.实验提示1首先应确定文件系统的数据结构:主目录、子目录及活动文件等。主目录和子目录都以文件的形式存放于磁盘,这样便于查找和修改。2用户创立的文件,可以编号存储于磁盘上。入fil
2、e0,file1,file2并以编号作为物理地址,在目录中进行登记。4.源代码#include<stdio.h> #include<string.h> #include<stdlib.h> #define MEM_D_SIZE 1024*1024 /总磁盘空间为1M#define DISKSIZE 1024/磁盘块的大小1K#define DISK_NUM 1024/磁盘块数目1K#define FATSIZE DISK_NUM*sizeof(struct fatitem)/FAT表大小#define ROOT_DISK_NO FATSIZE/DISKSIZ
3、E+1/根目录起始盘块号#define ROOT_DISK_SIZE sizeof(struct direct)/根目录大小#define DIR_MAXSIZE 1024/路径最大长度为1KB#define MSD 5/最大子目录数5#define MOFN 5/最大文件深度为5#define MAX_WRITE 1024*128/最大写入文字长度128KB struct fatitem /* size 8*/ int item; /*存放文件下一个磁盘的指针*/ char em_disk; /*磁盘块是否空闲标志位 0 空闲*/ ; struct direct /*-文件控制快信息-*/
4、struct FCB char name9; /*文件/目录名 8位*/ char property; /*属性 1位目录 0位普通文件*/ int size; /*文件/目录字节数、盘块数)*/ int firstdisk; /*文件/目录 起始盘块号*/ int next; /*子目录起始盘块号*/ int sign; /*1是根目录 0不是根目录*/ directitemMSD+2; ; struct opentable struct openttableitem char name9; /*文件名*/ int firstdisk; /*起始盘块号*/ int size; /*文件的大小
5、*/ openitemMOFN; int cur_size; /*当前打文件的数目*/ ; struct fatitem *fat; /*FAT表*/ struct direct *root; /*根目录*/ struct direct *cur_dir; /*当前目录*/ struct opentable u_opentable; /*文件翻开表*/ int fd=-1; /*文件翻开表的序号*/ char *bufferdir; /*记录当前路径的名称*/ char *fdisk; /*虚拟磁盘起始地址*/ void initfile(); void format(); void ente
6、r(); void halt(); int create(char *name); int open(char *name); int close(char *name); int write(int fd,char *buf,int len); int read(int fd,char *buf); int del(char *name); int mkdir(char *name); int rmdir(char *name); void dir(); int cd(char *name); void print(); void show(); void initfile() fdisk
7、= (char *)malloc(MEM_D_SIZE*sizeof(char); /*申请 1M空间*/ format(); void format() int i; FILE *fp; fat = (struct fatitem *)(fdisk+DISKSIZE); /*计算FAT表地址,引导区向后偏移 1k)*/ /*-初始化FAT表-*/ fat0.item=-1; /*引导块*/ fat0.em_disk='1' for(i=1;i<ROOT_DISK_NO-1;i+) /*存放 FAT表的磁盘块号*/ fati.item=i+1; fati.em_disk=
8、'1' fatROOT_DISK_NO.item=-1; /*存放根目录的磁盘块号*/ fatROOT_DISK_NO.em_disk='1' for(i=ROOT_DISK_NO+1;i<DISK_NUM;i+) fati.item = -1; fati.em_disk = '0' /*-*/ root = (struct direct *)(fdisk+DISKSIZE+FATSIZE); /*根目录的地址*/ /*初始化目录*/ /*-指向当前目录的目录项-*/ root->directitem0.sign = 1; root-
9、>directitem0.firstdisk = ROOT_DISK_NO; strcpy(root->,"."); root->directitem0.next = root->directitem0.firstdisk; root->perty = '1' root->directitem0.size = ROOT_DISK_SIZE; /*-指向上一级目录的目录项-*/ root->directitem1.sign = 1; root->dir
10、ectitem1.firstdisk = ROOT_DISK_NO; strcpy(root->,"."); root->directitem1.next = root->directitem0.firstdisk; root->perty = '1' root->directitem1.size = ROOT_DISK_SIZE; if(fp = fopen("disk.dat","wb")=NULL) printf(&quo
11、t;Error:n Cannot open file n"); return; for(i=2;i<MSD+2;i+) /*-子目录初始化为空-*/ root->directitemi.sign = 0; root->directitemi.firstdisk = -1; strcpy(root->,""); root->directitemi.next = -1; root->perty = '0' root->directitemi.size
12、 = 0; if(fp = fopen("disk.dat","wb")=NULL) printf("Error:n Cannot open file n"); return; if(fwrite(fdisk,MEM_D_SIZE,1,fp)!=1) /*把虚拟磁盘空间保存到磁盘文件中*/ printf("Error:n File write error! n"); fclose(fp); void enter() FILE *fp; int i; fdisk = (char *)malloc(MEM_D_SIZE
13、*sizeof(char); /*申请 1M空间*/ if(fp=fopen("disk.dat","rb")=NULL) printf("Error:nCannot open filen"); return; if(!fread(fdisk,MEM_D_SIZE,1,fp) /*把磁盘文件disk.dat 读入虚拟磁盘空间(内存)*/ printf("Error:nCannot read filen"); exit(0); fat = (struct fatitem *)(fdisk+DISKSIZE); /*找
14、到FAT表地址*/ root = (struct direct *)(fdisk+DISKSIZE+FATSIZE);/*找到根目录地址*/ fclose(fp); /*-初始化用户翻开表-*/ for(i=0;i<MOFN;i+) strcpy(u_,""); u_opentable.openitemi.firstdisk = -1; u_opentable.openitemi.size = 0; u_opentable.cur_size = 0; cur_dir = root; /*当前目录为根目录*/ buffer
15、dir = (char *)malloc(DIR_MAXSIZE*sizeof(char); strcpy(bufferdir,"Root:"); void halt() FILE *fp; int i; if(fp=fopen("disk.dat","wb")=NULL) printf("Error:nCannot open filen"); return; if(!fwrite(fdisk,MEM_D_SIZE,1,fp) /*把虚拟磁盘空间(内存)内容读入磁盘文件disk.dat */ printf(&quo
16、t;Error:nFile write error!n"); fclose(fp); free(fdisk); free(bufferdir); return;int create(char *name) int i,j; if(strlen(name)>8) /*文件名大于 8位*/ return(-1); for(j=2;j<MSD+2;j+) /*检查创立文件是否与已存在的文件重名*/ if(!strcmp(cur_dir->,name) break; if(j<MSD+2) /*文件已经存在*/ return(-4);
17、for(i=2;i<MSD+2;i+) /*找到第一个空闲子目录*/ if(cur_dir->directitemi.firstdisk=-1) break; if(i>=MSD+2) /*无空目录项*/ return(-2); if(u_opentable.cur_size>=MOFN) /*翻开文件太多*/ return(-3); for(j=ROOT_DISK_NO+1;j<DISK_NUM;j+) /*找到空闲盘块 j 后退出*/ if(fatj.em_disk='0') break; if(j>=DISK_NUM) return(-
18、5); fatj.em_disk = '1' /*将空闲块置为已经分配*/ /*-填写目录项-*/ strcpy(cur_dir->,name); cur_dir->directitemi.firstdisk = j; cur_dir->directitemi.size = 0; cur_dir->directitemi.next = j; cur_dir->perty = '0' /*-*/ fd = open(name); return 0; int open(cha
19、r *name) int i, j; for(i=2;i<MSD+2;i+) /*文件是否存在*/ if(!strcmp(cur_dir->,name) break; if(i>=MSD+2) return(-1); /*-是文件还是目录-*/ if(cur_dir->perty='1')return(-4); /*-文件是否翻开-*/ for(j=0;j<MOFN;j+) if(!strcmp(u_,name) break; if(j&l
20、t;MOFN) /*文件已经翻开*/ return(-2); if(u_opentable.cur_size>=MOFN) /*文件翻开太多*/ return(-3); /*-查找一个空闲用户翻开表项-*/ for(j=0;j<MOFN;j+) if(u_opentable.openitemj.firstdisk=-1) break; /*-填写表项的相关信息-*/ u_opentable.openitemj.firstdisk = cur_dir->directitemi.firstdisk; strcpy(u_,name);
21、 u_opentable.openitemj.size = cur_dir->directitemi.size; u_opentable.cur_size+; /*-返回用户翻开表表项的序号-*/ return(j); int close(char *name) int i; for(i=0;i<MOFN;i+) if(!strcmp(u_,name) break; if(i>=MOFN) return(-1); /*-清空该文件的用户翻开表项的内容-*/ strcpy(u_,&q
22、uot;"); u_opentable.openitemi.firstdisk = -1; u_opentable.openitemi.size = 0; u_opentable.cur_size-; return 0; int write(int fd, char *buf, int len) char *first; int item, i, j, k; int ilen1, ilen2, modlen, temp; /*-用 $ 字符作为空格 # 字符作为换行符-*/ char Space = 32; char Endter= 'n' for(i=0;i<
23、len;i+) if(bufi = '$') bufi = Space; else if(bufi = '#') bufi = Endter; /*-读取用户翻开表对应表项第一个盘块号-*/ item = u_opentable.openitemfd.firstdisk; /*-找到当前目录所对应表项的序号-*/ for(i=2;i<MSD+2;i+) if(cur_dir->directitemi.firstdisk=item) break; temp = i; /*-存放当前目录项的下标-*/ /*-找到的item 是该文件的最后一块磁盘块-*/
24、 while(fatitem.item!=-1) item =fatitem.item; /*-查找该文件的下一盘块-*/ /*-计算出该文件的最末地址-*/ first = fdisk+item*DISKSIZE+u_opentable.openitemfd.size%DISKSIZE; /*-如果最后磁盘块剩余的大小大于要写入的文件的大小-*/ if(DISKSIZE-u_opentable.openitemfd.size%DISKSIZE>len) strcpy(first,buf); u_opentable.openitemfd.size = u_opentable.openit
25、emfd.size+len; cur_dir->directitemtemp.size = cur_dir->directitemtemp.size+len; else for(i=0;i<(DISKSIZE-u_opentable.openitemfd.size%DISKSIZE);i+) /*写一局部内容到最后一块磁盘块的剩余空间(字节)*/ firsti = buf i; /*-计算分配完最后一块磁盘的剩余空间(字节) 还剩下多少字节未存储-*/ ilen1 = len-(DISKSIZE-u_opentable.openitemfd.size%DISKSIZE); i
26、len2 = ilen1/DISKSIZE; modlen = ilen1%DISKSIZE; if(modlen>0) ilen2 = ilen2+1; /*-还需要多少块磁盘块-*/ for(j=0;j<ilen2;j+) for(i=ROOT_DISK_NO+1;i<DISK_NUM;i+)/*寻找空闲磁盘块*/ if(fati.em_disk='0') break; if(i>=DISK_NUM) /*-如果磁盘块已经分配完了-*/ return(-1); first = fdisk+i*DISKSIZE; /*-找到的那块空闲磁盘块的起始地址-
27、*/ if(j=ilen2-1) /*-如果是最后要分配的一块-*/ for(k=0;k<len-(DISKSIZE-u_opentable.openitemfd.size%DISKSIZE)-j*DISKSIZE;k+) firstk = bufk; else/*-如果不是要最后分配的一块-*/ for(k=0;k<DISKSIZE;k+) firstk =bufk; fatitem.item = i; /*-找到一块后将它的序号存放在上一块的指针中-*/ fati.em_disk = '1' /*-置找到的磁盘快的空闲标志位为已分配-*/ fati.item =
28、 -1; /*-它的指针为 -1 (即没有下一块)-*/ /*-修改长度-*/ u_opentable.openitemfd.size = u_opentable.openitemfd.size+len; cur_dir->directitemtemp.size = cur_dir->directitemtemp.size+len; return 0; int read(int fd, char *buf) int len = u_opentable.openitemfd.size; char *first; int i, j, item; int ilen1, modlen; i
29、tem = u_opentable.openitemfd.firstdisk; ilen1 = len/DISKSIZE; modlen = len%DISKSIZE; if(modlen!=0) ilen1 = ilen1+1; /*-计算文件所占磁盘的块数-*/ first = fdisk+item*DISKSIZE; /*-计算文件的起始位置-*/ for(i=0;i<ilen1;i+) if(i=ilen1-1) /*-如果在最后一个磁盘块-*/ for(j=0;j<len-i*DISKSIZE;j+) bufi*DISKSIZE+j = firstj; else /*-不
30、在最后一块磁盘块-*/ for(j=0;j<len-i*DISKSIZE;j+) bufi*DISKSIZE+j = firstj; item = fatitem.item; /*-查找下一盘块-*/ first = fdisk+item*DISKSIZE; return 0; int del(char *name) int i,cur_item,item,temp; for(i=2;i<MSD+2;i+) /*-查找要删除文件是否在当前目录中-*/ if(!strcmp(cur_dir->,name) break; cur_item = i;
31、 /*-用来保存目录项的序号,供释放目录中-*/ if(i>=MSD+2) /*-如果不在当前目录中-*/ return(-1); if(cur_dir->directitemcur_perty!='0') /*-如果删除的(不)是目录-*/ return(-3); for(i=0;i<MOFN;i+) /*-如果文件翻开,那么不能删除,退出-*/ if(!strcmp(u_,name) return(-2); item = cur_dir->directitemcur_item.first
32、disk;/*-该文件的起始盘块号-*/ while(item!=-1) /*-释放空间,将FAT表对应项进行修改-*/ temp = fatitem.item; fatitem.item = -1; fatitem.em_disk = '0' item = temp; /*-释放目录项-*/ cur_dir->directitemcur_item.sign = 0; cur_dir->directitemcur_item.firstdisk = -1; strcpy(u_opentable.openitemcur_,"");
33、cur_dir->directitemcur_item.next = -1; cur_dir->directitemcur_perty = '0' cur_dir->directitemcur_item.size = 0; return 0; int mkdir(char *name) int i,j; struct direct *cur_mkdir; if(!strcmp(name,".") return(-4); if(!strcmp(name,".") return(-4); if(strlen(
34、name)>8) /*-如果目录名长度大于 8位-*/ return(-1); for(i=2;i<MSD+2;i+) /*-如果有空闲目录项退出-*/ if(cur_dir->directitemi.firstdisk=-1) break; if(i>=MSD+2) /*-目录/文件 已满-*/ return(-2); for(j=2;j<MSD+2;j+) /*-判断是否有重名-*/ if(!strcmp(cur_dir->,name) break; if(j<MSD+2) /*-如果有重名-*/ return(-3
35、); for(j=ROOT_DISK_NO+1;j<DISK_NUM;j+) /*-找到空闲磁盘块 j 后退出-*/ if(fatj.em_disk='0') break; if(j>=DISK_NUM) return(-5); fatj.em_disk='1' /*-将该空闲块设置为已分配-*/ /*-填写目录项-*/ strcpy(cur_dir->,name); cur_dir->directitemi.firstdisk=j; cur_dir->directitemi.size=ROOT_DI
36、SK_SIZE; cur_dir->directitemi.next=j; cur_dir->perty='1' /*-所创目录在虚拟磁盘上的地址(内存物理地址)-*/ cur_mkdir=(struct direct *)(fdisk+cur_dir->directitemi.firstdisk*DISKSIZE); /*-初始化目录-*/ /*-指向当前目录的目录项-*/ cur_mkdir->directitem0.sign=0; cur_mkdir->directitem0.firstdisk=cur_dir-
37、>directitemi.firstdisk; strcpy(cur_mkdir->,"."); cur_mkdir->directitem0.next=cur_mkdir->directitem0.firstdisk; cur_mkdir->perty='1' cur_mkdir->directitem0.size=ROOT_DISK_SIZE; /*-指向上一级目录的目录项-*/ cur_mkdir->directitem1.sign=cur_dir-
38、>directitem0.sign;cur_mkdir->directitem1.firstdisk=cur_dir->directitem0.firstdisk; strcpy(cur_mkdir->,"."); cur_mkdir->directitem1.next=cur_mkdir->directitem1.firstdisk; cur_mkdir->perty='1' cur_mkdir->directitem1.size=ROOT_DIS
39、K_SIZE; for(i=2;i<MSD+2;i+) /*-子目录都初始化为空-*/ cur_mkdir->directitemi.sign=0; cur_mkdir->directitemi.firstdisk=-1; strcpy(cur_mkdir->,""); cur_mkdir->directitemi.next=-1; cur_mkdir->perty='0' cur_mkdir->directitemi.size=0; return 0;
40、int rmdir(char *name) int i,j,item; struct direct *temp_dir; /*-检查当前目录项中有无该目录-*/ for(i=2;i<MSD+2;i+) if(!strcmp(cur_dir->,name) break; if(i>=MSD+2) /*-没有这个文件或目录-*/ return(-1);if(cur_dir->perty!='1')/*-删除的不是目录-*/ return(-3); /*-判断要删除的目录有无子目录-*/ temp_
41、dir=(struct direct *)(fdisk+cur_dir->directitemi.next*DISKSIZE); for(j=2;j<MSD+2;j+) if(temp_dir->directitemj.next!=-1) break; if(j<MSD+2) /*-有子目录或文件-*/ return(-2); /*-找到起始盘块号,并将其释放-*/ item=cur_dir->directitemi.firstdisk; fatitem.em_disk='0' /*-修改目录项-*/ cur_dir->directitemi
42、.sign=0; cur_dir->directitemi.firstdisk=-1; strcpy(cur_dir->,""); cur_dir->directitemi.next=-1; cur_dir->perty='0' cur_dir->directitemi.size=0; return 0; void dir() int i; for(i=2;i<MSD+2;i+) if(cur_dir->directitemi.firstdisk!=-1)
43、 /*-如果存在子目录-*/ printf("%st",cur_dir->); if(cur_dir->perty='0') /*-文件-*/ printf("%dttn",cur_dir->directitemi.size); else printf("t<目录>tn"); int cd(char *name) int i,j,item; char *str; char *temp,*point,*point1; struct
44、 direct *temp_dir; temp_dir=cur_dir; str=name; if(!strcmp("",name) cur_dir = root; strcpy(bufferdir,"Root:"); return 0; temp = (char *)malloc(DIR_MAXSIZE*sizeof(char);/*-最长路径名字分配空间-*/ for(i=0;i<(int)strlen(str);i+) tempi=stri; tempi='0' for(j=0;j<MSD+2;j+) /*-查找该子目录
45、是否在当前目录中-*/ if(!strcmp(temp_dir->,temp) break; free(temp);/*释放申请的临时空间*/ /if(temp_dir->perty!='1') /*-翻开的不是目录-*/ /return(-2); if(j>=MSD+2) /*-不在当前目录-*/ return(-1); item=temp_dir->directitemj.firstdisk; /*-当前目录在磁盘中位置-*/ temp_dir=(struct direct *)(fdis
46、k+item*DISKSIZE); if(!strcmp(".",name) if(cur_dir->directitemj-1.sign!=1) /*-如果上级目录不是根目录-*/ point=strchr(bufferdir,''); /查找字符串bufferdir中首次出现字符 的位置while(point!=NULL) point1=point+1; /*-减去''所占的空间,记录下次查找的起始地址-*/ point=strchr(point1,''); *(point1-1)='0' /*-将上
47、一级目录删除-*/ else /if(name0 !='') bufferdir = strcat(bufferdir,""); /*-修改当前目录-*/ bufferdir = strcat(bufferdir,name); cur_dir=temp_dir; /*-将当前目录确定下来-*/ return 0; void show() printf("%s>",bufferdir); void print() printf("*n");printf("*文件系统设计*n"); printf(
48、"*t命令格式说明*n"); printf("*tcd 目录名更改当前目录*n"); printf("*tmkdir 目录名创立子目录*n"); printf("*trmdir 目录名删除子目录*n"); printf("*tdir显示当前目录的子目录*n"); printf("*tcreate 文件名创立文件*n"); printf("*tdel 文件名删除文件*n"); printf("*topen 文件名翻开文件*n"); pri
49、ntf("*tclose 文件名关闭文件*n"); printf("*tread读文件*n"); printf("*twrite写文件*n"); printf("*texit退出系统*n"); printf("*n"); void main() FILE *fp; char ch; char a100; char code1110; char name10; int i,flag,r_size; char *contect; contect = (char *)malloc(MAX_WRITE*sizeof(char); if(fp=fopen("disk.dat","rb")=NULL) printf("You have not format,Do you want format?(y/n)"); scanf("%c",&ch); if
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年校招:中国航天科技集团面试题及答案
- 交友联谊会活动主持词
- 医院与消防救援站共建协议书7篇
- 《滕王阁序》原文+译文+注释+赏析
- 2025年山东省龙口市高二历史下册期末考试真题(B卷)附答案
- 2026云栖大会资料-「Agent 工程化」方向-稳定性数字人 从智能巡检、根因定位到受控自恢复 基于阿里云 AgentCore 的生产级 SRE Agent 实践
- 综合标准化工作指南 2025 版体系构建与项目实施
- 品牌联盟工作方案范文
- 流域水资源调度工作方案
- 2026年供应链采购成本控制项目分析方案
- 2026年血气分析采样护理方案
- 小学二年级道德与法治统编版上册《欢欢喜喜庆国庆》教学设计
- 科瑞智库:2026汉诺威国际车展全景洞察与趋势研判报告
- 2026年7月劳动关系协调师三级模拟试题+参考答案
- 2026事业单位工勤技能-吉林-吉林仓库管理员二级(技师)历年参考题库含答案详解
- T/CAIEC 084-2025城镇排水管道检测与评估技术规程
- 【《均值不等式在初等数学中的应用研究》6500字(论文)】
- 手术消毒铺单知识
- 互联网公司前端开发工程师工作绩效考评表
- 2025年文山州遴选公务员笔试真题汇编带答案解析
- 岩浆岩课件教学课件
评论
0/150
提交评论