操作系统实验八:文件结构(c++实现)

操作系统实验八 文件结构 模拟设计MS-DOS操作系统中磁盘文件的存储结构

一、实验内容
1、把文件的逻辑结构转换成存储结构
2、设计便于顺序存取和直接存取的文件存储结构。
二、实验目的
1、研究用户概念中的信息组织方式
2、理解文件的逻辑结构、存取结构、存取方式之间的联系
3、模拟设计文件的存储结构

三、实验题目

1、第一题:模拟设计MS-DOS操作系统中磁盘文件的存储结构。
[提示]:
⑴当用户对记录式文件采用顺序存以方式时,用户总是依次地访问一个个逻辑记录,即当访问了第i个记录后,下次总是访问第i+1个记录。所以,当用户采用顺序存取方式访问文件时,只要给出访问要求(读或写)而无需再指出要访问的记录号。
⑵采用链接文件结构,只有读出一个物理块信息后才能从链接字中得知下一个物理块号。所以,当用户要在文件中插入一些信息时,文件系
统必须多次地请求启动磁盘读出信息才能做插入工作。
在这里插入图片描述
• MS-DOS操作系统对链接文件结构作了改进,它是把所有的链接指针集中在一起,存放在文件定位表FAT中。查找链接字时不必读出物理块信息可直接从FAT中得到。
• 其设计思想是:假定磁盘上共有N个物理块可供使用,FAT就有N项,初始化时为全“0”,表示对应的物理块均可使用,当要存放文件时,从FAT中寻找为“0”的项,其对应的物理块用来存放文件信息,把文件的链接指针(指出物理块号)登记在FAT中,文件第一块块号登记在文件目录中。
在这里插入图片描述
⑶假定磁盘存储空间共有32个物理块,模拟设计文件定位表FAT。文件定位表可以用一个一维数组FAT[031]来定义,其中一个元素与一个物理块对应。当FAT[i]=0时,表示第i块为空闲块;当FAT[i]=FFF时,表示链接文件到第i块结束;当在0~FFF时,其值指示链接文件中下一个物理块号。
⑷每个物理块只能存放一个逻辑记录,设计一个程序把文件的逻辑结构模拟转换成MS-DOS的链接结构。
• 要求保存一个已经在主存中的文件时,给出文件名和文件的逻辑记录长度及个数,对一个已经保存的文件,允许用户插入新记录。用键输入来模拟用户的要求,输入信息为:“存” 文件名 逻辑记录长度 逻辑记录个数“插入” 文件名 逻辑记录号
• 模拟程序的算法如下图所示:
在这里插入图片描述
⑸ 假设系统中已经有两个链接文件,其链接情况由FAT表指出(链接情况学生自定),现又要保存一个新文件,然后对已保存的文件插入一个新记录。运行你所设计的程序,观察其结果。
思路
设计一个小菜单,有五个功能:1、新建文件2、修改文件3、删除文件4、查看文件目录5、查看文件定位表(FAT)
用链表结构表示文件目录,每次新建文件时在链表头部插入新的文件。
使用的数据结构如下:
struct Page//文件目录
{
string name;//文件名
int num;//起始块号
int length;//文件长度
Page *pre;
Page *next;
};
struct Node//物理块
{
int num;//为0时为空
string str;//逻辑记录
};
具体代码:

#include <iostream>
using namespace std;
struct Page//文件目录 
{
	string name;//文件名 
	int num;//起始块号
	int length;//文件长度 
	Page *pre;
	Page *next;
};
struct Node//物理块 
{
	int num;//为0时为空 
	string str;//逻辑记录	
};
int frees=32;//空闲物理块号 
Node node[32];

void init(Page *head)//初始化 
{
	for(int i=0;i<32;i++)
	{
		node[i].num=0;
		node[i].str="";
	}
	head->name=" ";
	head->num=-1;
	head->length=0;
	head->pre=NULL;
	head->next=NULL;
}
void create(Page *head)//新建文件 
{
	cout<<"请输入文件名\n";
	string str;
	cin>>str;
	Page *temp=new Page();
	Page *temp1=new Page();
	temp->name=str;
	for(temp1=head;temp1!=NULL;temp1=temp1->next) //文件名已存在 
	{
		if(str==temp1->name) 
		{
			cout<<"文件名已存在,请重新输入\n";
			delete temp;
			delete temp1;
			return ; 
		}
	}
	cout<<"请输入文件长度\n";
	int leng;
	cin>>leng;
	if(leng>frees) //判断是否有足够的空闲块 
	{
		cout<<"磁盘空间不足\n"; 
		delete temp;
		return ;
	}
	frees-=leng;
	cout<<"请输入文件内容\n"; 
	string str1[leng];
	for(int i=0;i<leng;i++)//输入文件内容
	{
		cin>>str1[i];
	}
	int cou=0;
	for(int i=0;i<leng;i++)
	{
		for(int j=0;j<32;j++)
		{
			if(node[j].num==0)//查找空闲块 
			{
				if(i==0) //起始块号 
				{
					cou=j;
					temp->num=j;
					temp->length=leng;

					temp->next = head->next;	//头插法插入新作业 
					if(head->next != NULL)
		        		head->next->pre = temp;
					temp->pre = head;
					head->next = temp;
					node[j].str=str1[i];
					node[cou].num=-1;
					
				}
				else if(i==leng-1)//末尾 
				{
					node[j].str=str1[i];
					node[cou].num=j;
					node[j].num=-1;
					
				}
				else//中间 
				{
					node[j].str=str1[i];
					node[cou].num=j;
					node[j].num=-1;
					cou=j;
				}
				break;
			}		
		}
	}
	cout<<"新建成功\n"; 
}

void change(Page *head)//插入内容,设定每次只能插入一段内容
{
	if(frees==0) {cout<<"无空闲块\n";return ;} 
	cout<<"请输入要修改的文件名\n";
	string str;
	cin>>str;
	Page *temp=new Page();
	for(temp=head;temp!=NULL;temp=temp->next) 
	{
		if(temp->name==str)     
		{ 
			temp->length++;
			cout<<"在第几段文件插入\n";
			int nu;
			cin>>nu;
			cout<<"请输入文件内容\n";
			string str1;
			cin>>str1;
			int temp1=temp->num;
			string temp2=str1;
			int i=1;
			string nk;
			while(1)//插入位置之后的内容后移 
			{	
				if(i==temp->length-1)
				{
					for(int k=0;k<32;k++)
					{
						if(node[k].num==0)
						{
							string nk2=temp2;
							temp2=node[temp1].str;
							node[temp1].num=k;
							node[temp1].str=nk2;
							temp1=k;
							break;
						}
					}
					node[temp1].str=temp2;
					node[temp1].num=-1;
					break;
				}
				nk=temp2;
				temp2=node[temp1].str;
				if(i>nu) node[temp1].str=nk;
				if(i==nu) node[temp1].str=str1;
				temp1=node[temp1].num;
				i++;
			} 
			cout<<"插入成功\n";
			frees--;//空闲块减一 
			return;	
		}
	}
	cout<<"文件名不存在"<<endl; 
} 
void shanchu(Page *head)//删除 
{
	cout<<"请输入要删除的文件名\n";
	string str;
	cin>>str;
	Page *temp=new Page();
	for(temp=head;temp!=NULL;temp=temp->next) 
	{
		if(temp->name==str)     
		{ 
			int i=temp->num;
			while(1)
			{
				frees++;//每次空闲块加1 
				node[i].str="";
				if(node[i].num==-1)
				{
					node[i].num=0;
					break;
				}
				int temp1=node[i].num;
				node[i].num=0;
				i=temp1;
			}
			temp->pre->next=temp->next;//删除输入的文件 
			if(temp->next!=NULL) temp->next->pre=temp->pre;
			cout<<"删除成功\n";
			delete temp;
			return ;
		}
	}
	cout<<"文件不存在\n";
}
void print1(Page *head)//打印文件目录 
{
	cout<<"文件目录如下:\n";
	cout<<"文件名       文件长度\n"; 
	Page *temp=new Page();
	for(temp=head->next;temp!=NULL;temp=temp->next)
	{
		cout<<temp->name<<"             "<<temp->length<<"\n";
	}
	delete temp;
}
void print2()//打印文件定位表 
{
	cout<<"块号        指向       内容"<<endl; 
	for(int i=0;i<32;i++)
	{
		cout<<i<<"           "<<node[i].num<<"         "<<node[i].str<<endl;
	}
}
int main()
{
	Page *head=new Page();
	init(head);
	while(1)
	{
		int choice;
		cout<<".....................................\n";
		cout<<"1、新建文件\n2、修改文件\n3、删除文件\n4、查看文件目录\n5、查看文件定位表(FAT)\n";
		cout<<".....................................\n";
		cin>>choice;
		switch(choice)
		{
			case 1:
				create(head);
				break;
			case 2:
				change(head);
				break;
			case 3:
				shanchu(head);
				break;
			case 4:
				print1(head);
				break;
			case 5:
				print2(); 
				break;
			default:
				cout<<"没有此操作,请重新输入\n";
		}	
	}	
} 
  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值