操作系統 實驗四 文件系統管理

實驗目的:

利用文件內容和命令實現樹型目錄結構。利用位示圖表示外存的分配情況,新建文件時分配必要的空間,模擬文件分配表(FAT)記錄文件在外存上的存儲方式。

內容要求:

 在文件中保存目錄內容,創建文件或子目錄可以用命令行命令:MD、CD、RD、MK(創建文

件)、DEL(刪除文件)和DIR。目錄項包括文件或目錄名稱、類型(文件、目錄或空目錄項)、創建日期以及下一個目錄項指針、下一級目錄項指針。

① 創建初始文件,建立根目錄的“.”和“..”目錄項。

②實現 ‘*’,‘?’的模糊查詢功能。

③ 輸入命令後根據命令含義完成相應文件操作:

MD:在目錄文件中創建子目錄,同時搜索當前目錄最後一個目錄項,並保存指針信息;

CD:根據當前目錄切換到指定目錄;

RD:搜索所要刪除的目錄是否爲空目錄,若是則刪除;

MK:在當前目錄中創建文件名稱;(申請空間利用位示圖修改FAT)

DEL:搜索所要刪除的文件是否存在,若是則刪除;(恢復位示圖修改FAT)

DIR:列出當前目錄的所有目錄項。

④ 在創建文件的時候分配空閒的磁盤空間,採用顯示鏈接的方式,利用文件分配表(FAT)記錄文件在外存上的存儲情況。

⑤當刪除文件時,回收外存上的空間,修改位示圖和文件分配表。


實現過程:

#include<iostream>
#include<time.h>
using namespace std;

struct FCB
{
		char	name[100];
		int		year,month,day,hour,minute,second;
		int		length;
		int		startaddr;
		int		node;
	
}fcb[1000];

struct Directory
{
		char	name[100][100];
		int		year,month,day,hour,minute,second;
		int		judge[100];			/*0爲文件夾,1爲文件*/
		int		link[100];		
		int		node;
		int		num;
}Dir[1000];

int		path = 1,Time = 1,used_fcb = 0,used_dir = 1;

int		step = 0;	
char	steps[100][100];		/*step保存當前工作路徑深度,steps保存當前工作路徑*/

int		FAT[256];	/*	FAT表	*/

int		Memory = 0;

char	bitmap[32];	/*	位示圖	*/

time_t T; /*用來存系統時間*/
struct tm *TimeP; /*用來存localtime傳回的地址*/	

void init(int n,int root)		/*對新結點初始化*/
{
		strcpy(Dir[n].name[0],".");
		strcpy(Dir[n].name[1],"..");
		Dir[n].judge[0]=Dir[n].judge[1] = 0;
		Dir[n].link[0]	= Time;
		Dir[n].link[1]	= root;
		Dir[n].node		= Time ++;
		Dir[n].num		= 2;
	

		T = time(NULL);
		TimeP = localtime( &T ); 
		Dir[n].year   = (TimeP->tm_year) +1900;
		Dir[n].month  = (TimeP->tm_mon) + 1;
		Dir[n].day    = (TimeP->tm_mday);
		Dir[n].hour   = (TimeP->tm_hour);
		Dir[n].minute = (TimeP->tm_min);
		Dir[n].second = (TimeP->tm_sec);
}
bool get_bit_map(int n);
void init_bit_map()	/*初始化位示圖*/
{
		int				i;
		for(i = 0 ; i < 32 ; i ++)
				bitmap[i] = rand()%256;
		for(i = 0 ; i < 256 ; i ++)
				FAT[i] = -1;
		for(i = 0 ; i < 256 ; i++)
				if(get_bit_map(i) == 0)
						Memory ++;

		
}

void show_bit_map()	/*顯示位示圖*/
{
		int				i,j;
		cout << "位示圖" <<endl;
		for(i = 0 ; i < 16 ; i ++)
		{
				for(j = 0 ; j < 16 ; j ++)
						printf("%d ",bool(bitmap[(i*16+j)/8] & (1<<(7-(i*16+j)%8))));
				cout<<endl;
		}
		
}


bool get_bit_map(int n)
{
		return bool(bitmap[n/8] & (1<<(7-n%8)));
}

void set_bit_map(int n,int k)
{
		if(k)
				bitmap[n/8]=bitmap[n/8] | (1<<(7-n%8));
		else
				bitmap[n/8]=bitmap[n/8] & ~(1<<(7-n%8));
}

void md()		/*創建文件夾*/
{
		int				i;
		char			 op[100];
		cin>>op;
		for(i = 2 ;i < Dir[path-1].num ; i ++)
				if(!Dir[path-1].judge[i] && !strcmp(Dir[path-1].name[i],op))
				{
						cout<<"文件夾已經存在"<<endl;
						return ;
				}
				
		init(used_dir++,path);
				
		Dir[path-1].judge[Dir[path-1].num] = 0;
		Dir[path-1].link[Dir[path-1].num]  = used_dir;
		strcpy(Dir[path-1].name[Dir[path-1].num],op);
		Dir[path-1].num++;
				
}

void rd()		/*	刪除文件夾	*/
{
		int				i,j;
		char op[100];
		cin>>op;
		for(i = 2 ; i < Dir[path-1].num ; i ++)
				if(!Dir[path-1].judge[i] && !strcmp(Dir[path-1].name[i],op))
				{
						if(Dir[Dir[path-1].link[i]-1].num  >2)
								cout<<"該文件夾不爲空, 不能刪除"<<endl;
						else
						{
								for(j = i ; j < Dir[path-1].num-1 ; j ++)
								{
										Dir[path-1].link[j]  = Dir[path-1].link[j+1];
										Dir[path-1].judge[j] = Dir[path-1].judge[j+1];
										strcpy(Dir[path-1].name[j],Dir[path-1].name[j+1]);
								}
								Dir[path-1].num--;
								cout<<"刪除成功"<<endl;
						}
						return ;
				}
		cout<<"該文件夾不存在"<<endl;
}

void fat()
{
		int				i,j,k;
		for(i = 2 ; i < Dir[path-1].num ; i ++)
		{
				if(Dir[path-1].judge[i])
				{
						cout << Dir[path-1].name[i] << ":" ;
						k = fcb[Dir[path-1].link[i]].startaddr;
						for(j=0;j<fcb[Dir[path-1].link[i]].length;j++)
						{
								cout << k << " ";
								k = FAT[k];
						}
						cout << endl;
				}
		}
}

void output_path()	/*輸出工作路徑*/
{
		cout<<endl<<"    C:\\";
		for(int i = 0 ; i <= step ; i ++)
		{
				if(i == step)
						break;
				else if(i == 0)
						cout<<steps[i];
				else
						cout<<"\\"<<steps[i];
		}
	
}


void dir()
{
		int				i;
		int				dir=0,file=0;
		int				sum=0;
		show_bit_map();
		output_path();
		cout << "的目錄" << endl << endl;

		for(i = 0 ; i < Dir[path-1].num ; i ++)
			if(!Dir[path-1].judge[i])
			{
					cout<<Dir[Dir[path-1].link[i]-1].year<<"-"<<Dir[Dir[path-1].link[i]-1].month<<"-"<<Dir[Dir[path-1].link[i]-1].day<<"\t"<<Dir[Dir[path-1].link[i]-1].hour<<":"<<Dir[Dir[path-1].link[i]-1].minute<<":"<<Dir[Dir[path-1].link[i]-1].second<<"\t";
					cout<<"<DIR>\t";
					cout<<Dir[path-1].name[i]/*<<"\t"<<Dir[Dir[path-1].link[i]-1].node*/<<endl;
					dir ++;
			}
			else
			{
					cout<<fcb[Dir[path-1].link[i]].year<<"-"<<fcb[Dir[path-1].link[i]].month<<"-"<<fcb[Dir[path-1].link[i]].day<<"\t"<<fcb[Dir[path-1].link[i]].hour<<":"<<fcb[Dir[path-1].link[i]].minute<<":"<<fcb[Dir[path-1].link[i]].second<<"\t\t";
					cout<<fcb[Dir[path-1].link[i]].length<<"\t";
					cout<<Dir[path-1].name[i]/*<<"\t"<<fcb[Dir[path-1].link[i]].node*/<<endl;
					sum += fcb[Dir[path-1].link[i]].length;
					file ++;
			}
		cout << "\t\t" << file << "個文件\t" << sum << "\t字節" << endl;
		cout << "\t\t"<< dir << "個目錄\t" << Memory << "\t可用字節" << endl;
		fat();
}


void _dir(char *choose)
{
	 int			i,j,k;
	 for(i = 0 ; i < Dir[path-1].num ; i ++)
	 {
				for(j=k=0;j<=strlen(Dir[path-1].name[i]);j++)
				{
						if(choose[k]== '*')
								k++;
						if(choose[k] != '*' && choose[k] != '?' && choose[k] == Dir[path-1].name[i][j])
							k++;
						else	if(choose[k] == '?')
							k++;

				}
				if(k>=strlen(choose))
				{
						if(!Dir[path-1].judge[i])
						{
								cout<<Dir[Dir[path-1].link[i]-1].year<<"-"<<Dir[Dir[path-1].link[i]-1].month<<"-"<<Dir[Dir[path-1].link[i]-1].day<<"\t"<<Dir[Dir[path-1].link[i]-1].hour<<":"<<Dir[Dir[path-1].link[i]-1].minute<<":"<<Dir[Dir[path-1].link[i]-1].second<<"\t";
								cout<<"\t<DIR>\t";
								cout<<Dir[path-1].name[i]<<endl;
						}
						else
						{
								cout<<fcb[Dir[path-1].link[i]].year<<"-"<<fcb[Dir[path-1].link[i]].month<<"-"<<fcb[Dir[path-1].link[i]].day<<"\t"<<fcb[Dir[path-1].link[i]].hour<<":"<<fcb[Dir[path-1].link[i]].minute<<":"<<fcb[Dir[path-1].link[i]].second<<"\t";
								cout<<fcb[Dir[path-1].link[i]].length<<"\t";
								cout<<Dir[path-1].name[i]<<endl;
				}

				}
	 }
}

bool output[100];

void tree(int p,int deep)
{
		int				i,j;
		for(i = 2 ; i < Dir[p-1].num ; i ++)
		{
				
				for(j = 0 ; j < deep ; j ++)
						if(output[j] == true)
								cout<<"│\t";
						else
								cout<<"\t";
				if(i < Dir[p-1].num-1)
						cout<<"├───"<<Dir[p-1].name[i]<<endl;
				else
						cout<<"└───"<<Dir[p-1].name[i]<<endl;

				output[deep] = false;
				if(i < Dir[p-1].num-1)
					output[deep] = true;

				if(!Dir[p-1].judge[i])
						tree(Dir[p-1].link[i],deep+1);
		}
}

void cd()
{
		char op[100];
		int i;
		cin>>op;
		if(!strcmp(op,"\\"))
		{
			path=1;
			step=0;	
			return ;
		}
		for(i = 0 ; i < Dir[path-1].num ; i ++)
				if(!Dir[path-1].judge[i] && !strcmp(Dir[path-1].name[i],op))
				{
						path=Dir[path-1].link[i];
						
						if(i == 1 && step)
								step--;
						else if(i != 1 && i)
						{
								strcpy(steps[step++],op);
						}
						
						return ;
				}
		cout<<"不存在該文件夾"<<endl;
}

void mk()
{
		int i,j,k;
		cin>>fcb[used_fcb].name;
		cin>>fcb[used_fcb].length;
		
		Memory -= fcb[used_fcb].length;

		for(i = 2 ; i < Dir[path-1].num ; i ++)
				if(Dir[path-1].judge[i] && !strcmp(Dir[path-1].name[i],fcb[used_fcb].name))
				{
						cout<<"文件重名,創建失敗"<<endl;
						return ;
				}
				
		for(i = j = 0 ; i < 256 && j < fcb[used_fcb].length ; i ++)
			if(!get_bit_map(i))
				j ++;
		if(i == 256)
		{
			cout<<"沒有足夠空間,不能創建文件"<<endl;
			return ;
		}
			
		for(i = j = 0 , k = -1 ; i < fcb[used_fcb].length ; i ++ , j ++)
		{
			while(get_bit_map(j))
				j ++;
			set_bit_map(j,1);
			if(k == -1)
				fcb[used_fcb].startaddr = j;
			else
				FAT[k] = j;
			k = j;
		}
		
		strcpy(Dir[path-1].name[Dir[path-1].num],fcb[used_fcb].name);
		fcb[used_fcb].node = Time++;
		Dir[path-1].link[Dir[path-1].num]  = used_fcb;
		Dir[path-1].judge[Dir[path-1].num] = 1;

		
		T = time(NULL);
		TimeP = localtime( &T ); 
		fcb[used_fcb].year = (TimeP->tm_year) + 1900;
		fcb[used_fcb].month  = (TimeP->tm_mon) + 1;
		fcb[used_fcb].day  = (TimeP->tm_mday) ;
		fcb[used_fcb].hour   = (TimeP->tm_hour);
		fcb[used_fcb].minute = (TimeP->tm_min);
		fcb[used_fcb].second = (TimeP->tm_sec);
	
		Dir[path-1].num++;
		used_fcb++;
		
}

void rk()		/*刪除文件*/
{
		int i,j,k;
		
		char na[100];
		cin>>na;
		for(i = 2 ; i < Dir[path-1].num ; i ++)
				if(Dir[path-1].judge[i] && !strcmp(Dir[path-1].name[i],na))
				{
						k = fcb[Dir[path-1].link[i]].startaddr;
						for(j=0;j<fcb[Dir[path-1].link[i]].length;j++)
						{
								set_bit_map(k,0);
								k = FAT[k];
								Memory ++;
						}
						
						for(j = i ; j < Dir[path-1].num-1 ; j ++)
						{
								Dir[path-1].link[j]  = Dir[path-1].link[j+1];
								Dir[path-1].judge[j] = Dir[path-1].judge[j+1];
								strcpy(Dir[path-1].name[j],Dir[path-1].name[j+1]);
						}
						Dir[path-1].num--;
						
						cout<<"刪除成功"<<endl;
						return ;
				}
		cout<<"沒找到文件"<<endl;
}

bool outputpath()	/*輸出工作路徑*/
{
		cout<<"C:\\>";
		for(int i = 0 ; i < step ; i ++)
		{
				cout<<steps[i]<<'>';
		}
		return true;
}

void choose()
{	
		char op[100],choose[100];
		
		while(outputpath()	&& cin>>op && strcmp(op,"exit"))
		{
				memset(choose,'\0',sizeof(choose));
				if(!strcmp(op,"cd"))
				{
						cd();
				}
				else if(!strcmp(op,"rd"))
				{
						rd();
				}
				else if(!strcmp(op,"md"))
				{
						md();
				}
				else if(!strcmp(op,"tree"))
				{
						tree(path,0);
						
				}
				else if(!strcmp(op,"mk"))
				{
						mk();
				}
				else if(!strcmp(op,"rk"))
				{
						rk();
				}
				else if(!strcmp(op,"dir"))
				{
						getchar();
						gets(choose);
						if(choose[0]!='\0')
								_dir(choose);
						else
								dir();
				}
				else if(!strcmp(op,"cls"))
				{
						system("cls");
				}
				
		}
		
}




int main()
{
		init(0,1);
		cout << "Microsoft Windows XP [版本 5.1.2600]\n(C) 版權所有 20092612 Zhang Bing.\n\n" << endl;
		init_bit_map();
		choose();
		return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章