第一篇:操作系统实习报告(磁盘文件操作)
大学
操作系统课程综合实践
题目:
磁盘文件操作
班级:
姓名:
学号:
指导教师:
2011年 12 月 23日
磁盘文件操作
摘要:
为了正确地实现文件的存取,文件系统设计了一组与存取文件有关的功能模块,用户可以用“访问指令”调用这些功能模块,以实现文件的存取要求。我们把文件系统设计的这一组功能模块称为“文件操作“,实验就是要模拟实现一些文件操作。文件操作不是独立的,它和文件系统的其他部分密切相关,若要实现文件操作就离不开文件的目录结构、文件的组织结构和磁盘空间的管理。因此,这个实习虽然是文件操作的模拟实现,但还是必须模拟一部分文件的组织结构、目录结构和磁盘空间管理的实现。
关键字:磁盘、文件、目录、分配表。
一、实验内容:
设计一个简单的文件系统,用文件模拟磁盘,用数组模拟缓冲区,要求实现; 1. 2. 3. 4. 支持多级目录结构,支持文件的绝对路径;
文件的逻辑结构采用流式结构,物理结构采用链接结构中的显示链接方式;
采用文件分配表;
实现的命令包括建立目录、列目录、删除空目录、建立文件、删除文件、显示文件内容、打开文件、读文件、写文件(追加方式)、关闭文件、改变文件属性。
最后编写主函数对所做工作进行测试。
二、实验目的:1、2、3、4、文件的操作。
文件的逻辑结构和物理结构 磁盘空间的管理 磁盘目录结构
三、实验环境: Windows XP、VC++
四、程序运行结果(详图):
程序运行的主界面:用户运行命令7-建立目录
用户运行命令1-建立文件:
显示目录内容:
打开文件:
写文件:
关闭文件:
再次显示目录内容:
以上为程序的运行的部分截图。
五、程序清单: #define false 0 #define true 1 #include “stdio.h” //#include
char name[3];/*文件或目录名*/ char type[2];/*文件类型名*/ char attribute;/*属性*/ char address;/*文件或目录的起始盘块号*/ char length;/*文件长度,以盘块为单位*/ }content;/*目录结构*/ #define n 5 /*模拟实验中系统允许打开文件的最大数量*/ typedef struct { int dnum;/*磁盘盘块号*/ int bnum;/*盘块内第几项*/ }pointer;/*已打开文件表中读写指针的结构*/ typedef struct {
char name[20];/*文件绝对路径名*/ char attribute;/*文件的属性,用1个字节表示,所以用了char类型*/ int number;/*文件起始盘块号*/ int length;/*文件长度,文件占用的字节数*/ int flag;/*操作类型,用“0”表示以读操作方式开文件,用“1”表示写操作pointer read;/*读文件的位置,文件刚打开时dnum为文件起始盘块号,bnumpointer write;/*写文件的位置,文件建立时dnum为文件起始盘块号,bnum方式打开文件*/ 为“0”*/ 为“0”,打开时为文件末尾*/ }OFILE;/*已打开文件表项类型定义*/ struct {
char buffer1[64];/*模拟缓冲1*/ content buffer2[8];/*模拟缓冲2*/ FILE *fc;/*模拟磁盘的文件指针*/
void copen(OFILE *x1,OFILE *x2)//OFILE *x1,*x2;{
} strcpy(x1->name,x2->name);x1->attribute=x2->attribute;x1->number=x2->number;x1->length=x2->length;x1->flag=x2->flag;x1->read.dnum=x2->read.dnum;x1->read.bnum=x2->read.bnum;x1->write.dnum=x2->write.dnum;x1->write.bnum=x2->write.bnum;OFILE file[n];/*已打开文件表*/ int length;/*已打开文件表中登记的文件数量*/ }openfile;/*已打开文件表定义*/
int sopen(char *name)/*在已打
开
文
件
表
中
查
找
文
件//P172 //char *name;{
void dopen(char *name)/*在已打开文件表中删除文件name*/ //char *name;{
int iopen(content *x)/*在已打开文件表中插入文件name*/ //content *x;{ int i;i=sopen(name);if(i==-1){
} copen(&openfile.file[i],&openfile.file[openfile.length-1]);openfile.length--;printf(“文件未打开n”);else int i;i=0;while(i name*/ 依次查找已打开文件表*/ if(i>=openfile.length)return(i);}/*查找sopen函数结束*/ }/*删除函数结束*/ int i;i=sopen(x->name);if(i!=-1){ } else if(openfile.length==n){ } else { } //copen(&openfile.file[openfile.length],x);openfile.length++;return(true);printf(“已打开文件表已满n”);return(false);printf(“文件已经打开n”);return(false);}/*填写已打开文件表函数结束*/ int allocate()/*分配一个磁盘块,返回块号*/ { */ //P173 int i;fseek(fc,0,SEEK_SET);/*将模拟磁盘的文件指针移至模拟磁盘FAT表*/ fread(buffer1,64L,1,fc);/*将FAT表中第一个磁盘块读入模拟缓冲for(i=3;i<63;i++)if(buffer1[i]==0){ /*FAT中的第i项为0,分配第i块磁盘块,修改FAT表,并且写回磁盘buffer1中*/ buffer1[i]=255; } fseek(fc,0,SEEK_SET);fwrite(buffer1,64L,1,fc);return(i);/*返回磁盘号*/ fread(buffer1,64L,1,fc);/*将FAT表中第二个磁盘块读入模拟缓冲for(i=0;i<63;i++) if(buffer1[i]==0){/*FAT中的第i项为0,分配第i+64块磁盘块,修改FAT表,并且写 } printf(“已经没有磁盘空间n”);return(false);buffer1[i]=255;fseek(fc,-64L,SEEK_CUR);fwrite(buffer1,64L,1,fc);return(i+64);/*返回磁盘号*/ buffer1中*/ 回磁盘*/ }/*分配磁盘块函数结束*/ int read_file(char *name,int length)/*读文件函数,文件路径名name,读取长度length*/ //char *name;//int length;{ int i,t;//char ch;if((i=sopen(name))==-1){ } if(openfile.file[i].flag==1){ printf(“文件以写方式打开,不能读n”);printf(“文件没有打开或不存在n”);return(false); } return 0;t=0;fseek(fc,openfile.file[i].read.dnum*64L,SEEK_SET);fread(buffer1,64,1,fc);while(t openfile.file[i].read.dnum=buffer1[openfile.file[i].read.dnum%64] } } t++;openfile.file[i].read.bnum=0;fseek(fc,openfile.file[i].read.dnum*64L,SEEK_SET);fread(buffer1,64,1,fc);/*读取下一个*/ 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);里是在屏幕上显示)*/;/*修改读指针*/ }/*读函数结束*/ int write_file(char *name,char *buff,int length)//P174 /*写文件函数*/ //char *name;/*文件路径名*/ //char *buff;/*存放准备写入磁盘的内容*/ //int length;/*写入内容的长度*/ { int i,t,dd;if((i=sopen(name))==-1)/*文件不存在,无法写*/ { } if(openfile.file[i].flag==0){ } t=0;fseek(fc,openfile.file[i].write.dnum*64L, SEEK_SET);fread(buffer1,64,1,fc);while(t 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);printf(“文件以读方式打开,不能写n”);return(false);printf(“文件没有打开或不存在n”);return(false);}/*if*/ 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;}/*if*/ t++;}/*while*/ 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的文件或目录,返回该目录的起始盘块号 */ //char *name;//int flag;/*flag=8表示查找目录,否则为文件*/ //int *dnum,*bnum;/*返回找到文件或目录的目录项的位置:盘块dnum中第bnum项*/ { for(s=0;name[k]!='.'&&name[k]!='/'&&s<3&&name[k]!=' ';s++,k++) pna[s]=name[k];pna[s]=' ';for(;s<3;s++)/*用空格补全名字长度*/ int k,i,s,j,last=0;char pna[3],type[2];if((strcmp(name,“")==0)||(strcmp(name,”/“)==0))/* return(2); 根 目录 */ //P175 k=0;if(name[0]=='/')k=1;i=2;/*i=根目录的起始盘块号*/ while(last!=1){ /*pna=从name中分离出”/“后一个目录名(或文件名)*/ */ & while(name[k]!='.'&&name[k]!=' '&&name[k]!='/')/*除去多余字符 k++;type[0]=type[1]=' ';if(name[k]=='.')/*取文件类型名type*/ if(flag==8){ } else {/*文件遇到类型名认为结束,后面的字符作废*/ } else if(name[k]!=' ')k++;if(name[k]==' ')last=1;/*查找目录且名字等于pna的目录项*/ fseek(fc,i*64L,SEEK_SET);fread(buffer2,64L,1,fc);j=0;if(last==1&&flag!=8)k++;if(name[k]!=' ')type[0]=name[k];k++;if(name[k]!=' ')type[1]=name[k];if(name[k]!=' '&&name[k+1]!=' '){ } last=1;printf(”文件名错误n“);return(false);printf(”目录不应该有有类型名,查找失败n“);return(false);while(j<8&&!(buffer2[j].attribute!=8&&buffer2[j].name[0]==pna[0]& j++;buffer2[j].name[1]==pna[1]&&buffer2[j].name[2]==pna[2]&& buffer2[j].type[0]==type[0]&&buffer2[j].type[1]==type[1]))else while(j<8&&!(buffer2[j].attribute==8&&buffer2[j].name[0]==pna[0]& &&buffer2[j].name[2]==pna[2]))j++; if(last==1)/*查找结束*/ { *dnum=i;*bnum=j; return(buffer2[j].address);&buffer2[j].name[1]==pna[1] if(j<8)/*找到该目录或文件*/ } else/*查找还未结束*/ i=buffer2[j].address;/*读取下一个盘块*/ return(false);else //P176 }/*while 查找结束*/ }/*search()结束*/ int create_file(char *name,int attribute)/*建立文件函数,路径名name,文件属性attribute*/ //char *name;//int attribute;{ int i,j,k,s,d,t,b,dd,dn,bn;char dname[3],tname[2],pathname[20]; OFILE x;if(attribute%2==1){ } if(openfile.length==n){ } /* 将name分成两部分,目录路径pathname和目录名dname*/ for(j=0;name[j]!=' ';j++)/*查找最后一个“/”*/ if(name[j]=='/')s=j;/*分离目录路径*/ for(j=0;j