⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file.h

📁 模拟操作系统,主要完成了文件管理,程管理等
💻 H
📖 第 1 页 / 共 2 页
字号:
#define false 0
#define true 1
#include "stdio.h"
#include <string.h>

typedef struct 
{
	char name[3];    /*文件或目录名*/
	char type[2];      /*文件类型名*/
	char attribute;     /*属性*/
	char address;       /*文件或目录的起始盘块号*/
	char length;       /*文件长度,以盘块为单位*/
}content;          /*目录结构*/

typedef struct
{ 
	int dnum;         /*磁盘盘块号*/
	int bnum;          /*磁盘盘块内第几个字节*/
}pointer;
          /*已打开文件表中读写指针的结构*/
typedef struct
{ 
	char name[20];		/*文件绝对路径名*/
	char attribute;
	int number,flag;    /*文件的属性,用1个字节表示,char类型*/
	int length;			/*文件长度,文件占用的字节数int  flag;*/
						/*操作类型,用"0"表示以读操作方式开文件的,用"1"表写操作方式打开文件的*/
	pointer read;     /*读文件的位置,文件刚打开时dnum为文件起始盘*/
	pointer write;   /*写文件的位置,文件刚建立时dnum为文件起始盘块号,bnum为"0",文件打开时为文件的末尾*/
}OFILE;             /*已打开文件表项类型定义*/
#define fn 5        /*模拟实验中系统允许打开文件的最大数量*/
struct
{
	OFILE file[fn];    /*已打开文件表*/
	int length;        /*已打开文件表中登记的文件数量*/
}openfile;         /*已打开文件表定义*/


char buffer1[64];   /*模拟缓冲1*/
content buffer2[8]; /*模拟缓冲2*/
FILE *fc;           /*模拟磁盘的文件的指针*/

copen(OFILE *x1,OFILE *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;
}

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);
} /*查找函数sopen结束*/

dopen(char *name)
/*在已打开文件表中删除文件name*/
{
	int i;
	i=sopen(name);
	if(i==-1)
		printf("文件未打开\n");
	else
	{
		copen(&openfile.file[i], &openfile.file[openfile.length-1]);
		openfile.length--;
	}
} /*删除函数dopen结束*/

iopen(OFILE  *x)
/*在已打开文件表中插入n文件x->name*/
{
	int i;
	i=sopen(x->name);
	if(i!=-1)
	{
		printf("文件已经打开\n");
		return(false);
	}
	else 
		if(openfile.length==fn)
		{
			printf("已打开文件表已满\n");
			return(false);
		}
		else
		{
			copen(&openfile.file[openfile.length],x);
			openfile.length++;
			return(true);
		}
}/* 填写已打开文件表函数结束 */
allocate()
/* 分配一个磁盘块,返回块号 */
{
	int i;
	fseek(fc,0,SEEK_SET);      /*将模拟磁盘的文件指针移至模拟磁盘FAT表*/
	fread(buffer1,64L,1,fc);   /*将FAT表中第一个盘块读入模拟缓冲buffer1中*/
	for(i=3;i<63;i++)
		if(buffer1[i]==0)      /*FATk中的第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表中第二个盘块读入模拟缓冲buffer1中*/
		for(i=0;i<63;i++)
			if(buffer1[i]==0)        /*FAT中的第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);
}/* 分配磁盘块函数结束 */

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++;
	}
}/*读函数结束*/

/*写文件函数
char *name    文件路径名
char *buff    存放准备写入磁盘的内容
int length    写入内容的长度*/

write_file(char *name,char *buff,int 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--;
				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);
	printf("写文件完成.");
}

/*查找路径名为name的文件或目录,返回该目录的起始盘块号
char *name;
int flag;  /*flag=8表示查找目录,否则为文件
int * dnum,*bnum ; /*返回文件或目录的目录项登记位置,盘块dnum中第bnum项*/
search(char *name,int flag,int *dnum,int *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]='\0';
		if(name[k]=='.')   /*取文件类型名type*/
			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;
			}
		else
			if(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]&&buffer2[j].type[0]==type[0]&&buffer2[j].type[1]==type[1]))
			j++;
		else                   /*查找名字等于pna的目录项*/
			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++;
		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()结束 */

/*建立文件函数,路径名name,文件属性attribute*/
create_file(char *name,int 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==fn)
	{
		printf("已打开表已满,不能建立\n");
		return(false);
	}
	/*将name分成两部分,目录路径pathname和目录名dname*/
	for(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]=' ';
		k=0;
		if(name[j++]=='.')   /*分离类型名*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -