操作系统实验五

实验五: 文件系统

一、实验目的

本实验要求在模拟的I/O系统之上开发一个简单的文件系统。用户通过create, open, read等命令与文件系统交互。文件系统把磁盘视为顺序编号的逻辑块序列,逻辑块的编号为0至L−1。I/O系统利用内存中的数组模拟磁盘。

二、概要设计

文件系统提供如下函数;create, destroy, open, read, write。

• int create(filename): 根据指定的文件名创建新文件。

找到一个空闲的文件描述符。

在文件目录中为新创建的文件分配一个目录项(可能需要为目录文件分配新的磁盘块)。

在分配的目录项中记录文件名以及描述符编号。

返回状态信息(如有无错误发生等)。

• int destroy(filename): 删除指定文件。

在目录中搜索该文件的描述符编号。

删除该文件对应的目录项并更新位图。

释放文件描述符。

返回状态信息。

•int open(filename): 打开文件。该函数返回的索引号可用于后续的read, write, lseek,或close操作。

搜索目录找到文件对应的描述符编号。

在打开文件表中分配一个表目。

在分配到的表目中把读写指针置为0,并记录描述符编号。

读入文件的第一块到读写缓冲区中。

返回分配到的表目在打开文件表中的索引号。

•int close(index): 关闭指定文件

把缓冲区的内容写入磁盘。

释放该文件在打开文件表中对应的表目。

返回状态信息。

•int read(index, mem_area, count): 从指定文件顺序读入count个字节memarea指定的内存位置。读操作从文件的读写指针指示的位置开始。

计算读写指针对应的位置在读写缓冲区中的偏移。

把缓冲区中的内容拷贝到指定的内存位置,直到发生下列事件之一。

到达文件尾或者已经拷贝了指定的字节数。这时,更新读写指针并返回相应信息。

到达缓冲区末尾。这时,把缓冲区内容写入磁盘,然后把文件下一块的内容读入磁盘。最后返回第2步。

•int write(index, mem_area, count): 把mem_area指定的内存位置开始的count个字节顺序写入指定文件。写操作从文件的读写指针指示的位置开始。

写的内容若小于缓冲区内容,则直接写入缓冲区,完成写操作。

写入的内容,缓冲区若无法一次装完,则需要填满缓冲区,然后将缓冲区写入文件,腾出缓冲区。

然后再写入缓冲区,碰到缓冲区满的情况便写入文件,腾出缓冲区,以便文件的写入,完成写操作。

返回状态信息。

•int lseek(index, pos): pos是一个整数,表示从文件开始位置的偏移量。

把文件的读写指针移动到pos指定的位置。

文件打开时,读写指针自动设置为0。

每次读写操作之后,它指向最后被访问的字节的下一个位置。

lseek能够在不进行读写操作的情况下改变读写指针能位置。

三、详细设计及测试结果

创建文件:

int create(char filename[])
{
	int i;
	int frees;
	int	freed;
	int freed2;
	char temps[B];
	char tempc[B];
	char temp[B];
	for(i = K ; i < K+FILE_NUM ; i++)
	{
		read_block((i-K)/B,temp);
		if(temp[(i-K)%B] == BUSY)
		{
			read_block(i,temp);
			if(strncmp(temp+1,filename,FILE_NAME_LENGTH) == 0)
			{
				printf("该目录已经存在文件名为%s的文件\n",filename);
				return ERROR;
			}
		}
	}
	for(i = FILE_SIGN_AREA ; i < K; i ++)
	{
		read_block(i,temp);
		if(temp[0] == FREE)
		{
			frees = i;
			break;
		}
	}
	if(i == K)
	{
		printf("没有空闲的文件描述符\n");
		return ERROR;
	}
	for(i = K ; i < K+FILE_NUM ; i++)
	{
		read_block((i-K)/B,temp);
		if(temp[(i-K)%B] == FREE)
		{
			freed = i;
			break;
		}
	}
	if(i == K+FILE_NUM)
	{
		printf("文件个数已达上限\n");
		return ERROR;
	}
	for(i = K + FILE_NUM; i < L ; i++)
	{
		read_block((i-K)/B,temp);
		if(temp[(i-K)%B] == FREE)
		{
			freed2 = i;
			break;
		}
	}
	if(i == L)
	{
		printf("磁盘已满,分配失败\n");
		return ERROR;
	}
	filesign temp_filesign;
	contents temp_contents;

	temp_filesign.filesign_flag = 1;
	temp_filesign.file_length = 0;
	temp_filesign.file_block = 1;


	Init_block(temps,B);
	temps[0] = temp_filesign.filesign_flag;
	temps[1] = temp_filesign.file_length;
	temps[2] = temp_filesign.file_block;
	temps[3] = freed2;
	for(i = 4 ; i < FILE_BLOCK_LENGTH ; i++)
	{
		temps[i] = '\0';
	}
	write_block(frees,temps);

	temp_contents.filesignnum = frees - FILE_SIGN_AREA;
	strncpy(temp_contents.filename,filename,FILE_NAME_LENGTH);

	Init_block(tempc,B);
	tempc[0] = temp_contents.filesignnum;
	tempc[1] = '\0';
	strcat(tempc,temp_contents.filename);
	write_block(freed,tempc);

	read_block((freed-K)/B,temp);
	temp[(freed-K)%B] = BUSY;
	write_block((freed-K)/B,temp);

	read_block((freed2-K)/B,temp);
	temp[(freed2-K)%B] = BUSY;
	write_block((freed2-K)/B,temp);

	read_block(FILE_SIGN_AREA,temp);
	temp[1]++;
	write_block(FILE_SIGN_AREA,temp);

	return OK;


}

删除文件:

int destroy(char * filename)
{
	int i;
	int dtys;
	int dtyd;
	int use_block;
	int index;
	char temp[B];
	char tempd[B];

	for(i = K ; i < K+FILE_NUM ; i++)
	{
		read_block((i-K)/B,temp);
		if(temp[(i-K)%B] == BUSY)
		{
			read_block(i,temp);
			if(strncmp(temp+1,filename,FILE_NAME_LENGTH) == 0)
			{
				dtyd = i;
				dtys = temp[0] + FILE_SIGN_AREA;
				index = temp[0];
				break;
			}
		}
	}
	if(i == K+FILE_NUM)
	{
		printf("没有找到该文件\n");
		return ERROR;
	}

	int list = -1;
	for(i = 0; i < FILE_NUM ; i++)
	{
		if(open_list[i].filesignnum == index)
		{
			list = i;
			break;
		}
	}
	if(open_list[list].flag == BUSY && list != -1)
	{
		printf("该文件已经被打开,需要关闭才能删除\n");
		return ERROR;
	}

	read_block(dtys,temp);
	use_block = temp[2];
	for(i = 0 ; i < use_block ; i++)
	{
		read_block((temp[i+3]-K)/B,tempd);
		tempd[(temp[i+3]-K)%B] = FREE;
		write_block((temp[i+3]-K)/B,tempd);
	}
	Init_block(temp,B);
	write_block(dtys,temp);


	Init_block(temp,B);
	write_block(dtyd,temp);


	read_block((dtyd-K)/B,temp);
	temp[(dtyd-K)%B] = FREE;
	write_block((dtyd-K)/B,temp);

	read_block(FILE_SIGN_AREA,temp);
	temp[1]--;
	write_block(FILE_SIGN_AREA,temp);


	return OK;

}

打开文件:

int open(char * filename)
{
	int i;
	int opd;
	int ops;
	int list;
	char temp[B];
	int index;

	for(i = K ; i < K+FILE_NUM ; i++)
	{
		read_block((i-K)/B,temp);
		if(temp[(i-K)%B] == BUSY)
		{
			read_block(i,temp);
			if(strncmp(temp+1,filename,FILE_NAME_LENGTH) == 0)
			{
				opd = i;
				ops = temp[0] ;
			//	printf("opd: %d,ops: %d\n",opd,ops);
				break;
			}
		}
	}
	if(i == K+FILE_NUM)
	{
		printf("没有找到该文件\n");
		return ERROR;
	}

	for(i = 0 ; i < FILE_NUM ; i++)
	{
		if(open_list[i].filesignnum == ops && open_list[i].flag == BUSY)
		{
			printf("该文件已经被打开\n");
			return ERROR;
		}
	}


	for(i = 0 ; i < FILE_NUM ; i++)
	{
		if(open_list[i].flag != BUSY)
		{
			list = i;
			break;
		}
	}


	open_list[list].filesignnum = ops;
	open_list[list].flag = BUSY;

	index = open_list[list].filesignnum;
	lseek(index,0);

	Init_block(open_list[list].buffer,BUFFER_LENGTH);
	read_block(open_list[list].pointer[0],temp);
	strncpy(open_list[list].buffer,temp,BUFFER_LENGTH);

	return OK;

}

关闭文件:

int close(int index)
{
	int i;
	int list = -1;
	char temp[B];

	for(i = 0; i < FILE_NUM ; i++)
	{
		if(open_list[i].filesignnum == index)
		{
			list = i;
			break;
		}
	}
	if(list == -1)
	{
		printf("没找到当前索引号文件,操作失败\n");
		return ERROR;
	}
	if(open_list[list].flag != BUSY)
	{
		printf("输入的索引号有误,操作失败\n");
		return ERROR;
	}


	write_buffer(index,list);


	Init_block(open_list[list].buffer,BUFFER_LENGTH);
	open_list[list].filesignnum = FREE;
	open_list[list].flag = FREE;
	open_list[list].pointer[0] = NULL;
	open_list[list].pointer[1] = NULL;
	return OK;
}

文件的读操作:

int read(int index, int mem_area, int count)
{
	int i;
	int list = -1;
	char temp[B];
	for(i = 0; i < FILE_NUM ; i++)
	{
		if(open_list[i].filesignnum == index)
		{
			list = i;
			break;
		}
	}
	if(list == -1)
	{
		printf("没找到当前索引号文件,操作失败\n");
		return ERROR;
	}
	if(open_list[list].flag != BUSY)
	{
		printf("输入的索引号有误,操作失败\n");
		return ERROR;
	}

	char temp_output[OUTPUT_LENGTH];
	Init_block(temp_output,OUTPUT_LENGTH);
	char output[OUTPUT_LENGTH];
	Init_block(output,OUTPUT_LENGTH);

	read_block(FILE_SIGN_AREA+index,temp);
	int file_length = temp[1];
	int file_block = temp[2];
	int file_area;

	for(i = 0; i < file_block - 1 ; i++)
	{
		read_block(FILE_SIGN_AREA+index,temp);
		read_block(temp[3+i],temp);
		strncpy(temp_output+i*B,temp,B);
	}
	read_block(FILE_SIGN_AREA+index,temp);
	read_block(temp[3+i],temp);
	strncpy(temp_output+i*B,temp,B);

	int x = open_list[list].pointer[0];
	int y = open_list[list].pointer[1];

	for(i = 0 ; i < file_block ; i++)
	{
		read_block(FILE_SIGN_AREA+index,temp);
		if(temp[3+i] == x)
		{
			break;
		}
	}
	file_area = i * B + y;

	for(i = 0 ;  i < count ; i++)
	{
		output[i+mem_area] = temp_output[i+file_area];
	}

	printf("%s\n",output+mem_area);
	return OK;
}

文件的写操作:

int write(int index,int mem_area,int count)
{
	int i;
	int list = -1;
	int input_length;
	char temp[B];

	for(i = 0; i < FILE_NUM ; i++)
	{
		if(open_list[i].filesignnum == index)
		{
			list = i;
			break;
		}
	}
	if(list == -1)
	{
		printf("没找到当前索引号文件,操作失败\n");
		return ERROR;
	}
	if(open_list[list].flag != BUSY)
	{
		printf("输入的索引号有误,操作失败\n");
		return ERROR;
	}

	char input[INPUT_LENGTH];
	Init_block(input,INPUT_LENGTH);
	i = 0;
	fflush(stdin);
	while(scanf("%c",&input[i]))
	{
		if(input[i] == '\n')
		{
			input[i] == '\0';
			break;
		}
		i++;
	}
	input_length = i;

	if(count <= BUFFER_LENGTH )
	{
		strncat(open_list[list].buffer,input+mem_area,count);
	}
	else
	{
		int rest;
		for(i = 0; i < BUFFER_LENGTH ; i++)
		{
			if(open_list[list].buffer[i] == FREE)
			{
				rest = BUFFER_LENGTH - i;
				break;
			}
		}
		strncat(open_list[list].buffer+BUFFER_LENGTH-rest,input + mem_area,rest);
		write_buffer(index,list);
		Init_block(open_list[list].buffer,BUFFER_LENGTH);
		for(i = 0; i < (count/BUFFER_LENGTH)-1 ; i++)
		{
			strncpy(open_list[list].buffer,(input+mem_area)+rest+i*BUFFER_LENGTH,BUFFER_LENGTH);

			write_buffer(index,list);
			Init_block(open_list[list].buffer,BUFFER_LENGTH);
		}

		Init_block(open_list[list].buffer,BUFFER_LENGTH);
		strncpy(open_list[list].buffer,(input+mem_area)+rest+i*BUFFER_LENGTH,count%BUFFER_LENGTH);
		int buffer_start;
	}
	return OK;
}

目录:

 

新建文件并查看:

删除文件并查看:

 

打开文件:

 

写操作:

 

关闭文件:

 

后台查看磁盘数组的内容,可以查看实时情况命令(ldisk)

 

GitHub源码:https://github.com/wwyw/lab5

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值