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

📄 myfs.txt

📁 这是我写的一个用于测试的文件系统
💻 TXT
📖 第 1 页 / 共 4 页
字号:
{                                                  //否则返回-1
	int parent,p=0,index;
	parent=get_parent(old_name,p);                 //跟对目录重命名一样
	if(parent==-1)
	{
		printf("Path name error!\n");
		return -1;
	}
	int file_id=search(parent,old_name+p,1,index);
	if(file_id==-1)
	{
		printf("The file not exist!\n");
		return -1;
	}
	if(strcmp(old_name+p,new_name)!=0 && search(parent,new_name,1,index)!=-1)
	{
		printf("File name repeated!\n");
		return -1;
	}
	strcpy(file[file_id].file_name,new_name);
	al_file[file_id]++;
	return file_id;
}

void del_file(int pos)                             //删除文件,调用该函数的前提是已经取得要删除文件                   
{                                                  //的索引号
	return_block(pos);                             //释放磁盘块
	file_flag[pos]=0; 
	used_file--;
	al_fflag[pos]++;
	al_file[pos]=0;

	if(open_files[pos]>0)                          //如果已经获得缓冲区,则立即释放
	{
		int buf_id=get_buffer_id(pos);
		buffer[buf_id].flag=0;
		open_files[pos]=0;
	}
}

int del_file(int parent,char *file_name)           //在指定的目录下删除文件,删除成功则返回文件的              
{                                                  //索引号,否则返回-1
	int del_pos,index;
	if((del_pos=search(parent,file_name,1,index))==-1)//搜索该文件是否存在,不存在则删除失败
	{
		printf("The file to delete not exist!\n");
		return -1;
	}
	del_file(del_pos);                             //开始删除文件

	struct dir_node *p=&dir[parent];               //修改父目录的控制信息
	if(p->file_count>=2)
	{
		int top=p->file_count-1;         	
		p->child_file[index]=p->child_file[top];
	}
	p->file_count--;
	al_dir[parent]++;

	return del_pos;
}

int delfile(char *name)                            //删除文件的主调函数
{
	int parent,p=0;
	parent=get_parent(name,p);
	if(parent==-1)
	{
		printf("Path name error!\n");
		return -1;
	}
	return del_file(parent,name+p);
}

void del_dir(int pos)                              //删除指定的目录节点,该目录已经为空                     
{
	dir_flag[pos]=0;  
	used_dir--;
	al_dflag[pos]++;
	al_dir[pos]=0;
}

void del(int pos)                                  //删除一个指定目录及它下面的所有文件及所有目录                           
{
	for(int i=0;i<dir[pos].file_count;i++)         //删除当前目录下的所有文件
		del_file(dir[pos].child_file[i]);
	for(i=0;i<dir[pos].dir_count;i++)              //删除子目录
		del(dir[pos].child_dir[i]);
	del_dir(pos);                                  //删除当前目录
}

void del_dir(int parent,int del_pos,int index)     //在一个指定的目录下删除一个目录及它下面的所有                 
{                                                  //文件及所有目录
	del(del_pos);                                  //开始删除目录
	if(dir[parent].dir_count>=2)                   //修改父目录的控制信息
	{
		int top=dir[parent].dir_count-1;
		dir[parent].child_dir[index]=dir[parent].child_dir[top];
	}
	dir[parent].dir_count--;
	al_dir[parent]++;
}

void paste(int dir_id)                             //用于设置当前路径
{
	if(dir_id==0)
		return;
	paste(dir[dir_id].parent);
	strcat(curr_path,dir[dir_id].dir_name);
	strcat(curr_path,"/");
}

int change_dir(char *name)                         //改变工作目录,成功则返回该目
{                                                  //录的索引号,否则返回-1
	int parent,p=0,pos,index;
	if(strcmp(name,"/")==0)
		pos=0;
	else if(strcmp(name,"..")==0)
		pos=curr_dir->parent;
	else
	{	
		parent=get_parent(name,p);	
		if(parent==-1)	
		{		
			printf("Path name error!\n");		
			return -1;	
		}
		pos=search(parent,name+p,0,index);
	}
	if(pos==-1)                                    //如果该目录不存在,则失败
	{
		printf("The dictory not exist!\n");
		return -1;
	}
	curr_path[3]='\0';
	paste(pos);
	curr=pos;                                      //改变当前目录及路径
	curr_dir=&dir[curr];                                                 
	return curr;                               
}

int count[DIR_NUM];                                //用于显示目录树时用

void print_sp(int dir_id)                          //该函数用于打印|用,可以将目录结构以树形
{                                                  //显示
	if(dir_id<0)
		return;
	print_sp(dir[dir_id].parent);
	if(dir[dir_id].dir_count>count[dir_id])
		printf("|");
	else
		printf(" ");
	for(int i=0;i<6;i++)
		printf(" ");
}

void print_pre(int id,int type)                    //该函数在每打印一个目录或文件名之前调用
{
	int parent,pre;
	if(type==0)
		parent=dir[id].parent;
	else
		parent=file[id].parent;
	pre=dir[parent].parent;
	print_sp(pre);
}

void print_file(int file_id)                       //打印文件名
{
	print_pre(file_id,1);
	printf("|");
	for(int i=0;i<6;i++)
		printf("_");
	printf("%s\n",file[file_id].file_name);
}

void print_dir(int dir_id)                         //打印目录名
{
	print_pre(dir_id,0);
	printf("|");
	for(int i=0;i<6;i++)
		printf("_");
	printf("%s\057\n",dir[dir_id].dir_name);
	count[dir[dir_id].parent]++;
}

void print(int dir_id)                             //打印树形结构的核心函数
{
	print_dir(dir_id);
	for(int i=0;i<dir[dir_id].file_count;i++)
		print_file(dir[dir_id].child_file[i]);
	for(i=0;i<dir[dir_id].dir_count;i++)
		print(dir[dir_id].child_dir[i]);
}

void show_tree()                                   //打印树形结构的主调函数
{
	if(used_file==0 && used_dir==1)
	{
		printf("The file system is empty!\n");
		return;
	}
	printf("%s\057\n",dir[0].dir_name);
	for(int i=0;i<DIR_NUM;i++)
		count[i]=0;
	for(i=0;i<dir[0].file_count;i++)
		print_file(dir[0].child_file[i]);
	for(i=0;i<dir[0].dir_count;i++)
		print(dir[0].child_dir[i]);
}

void show_dir(int dir_id)                          //以下几个函数用于显示当前目录下面的目录和文件,
{                                                  //跟上面不同的是,它不能显示目录及文件之间的关系,
	printf("%s",dir[dir_id].dir_name);             //但它可以显示一些细节,如创建时间,文件长度
	for(int i=strlen(dir[dir_id].dir_name);i<20;i++)
		printf(" ");
	printf("<DIR>");
	for(i=25;i<30;i++)
		printf(" ");
	printf("%d-%.2d-%.2d %.2d:%.2d:%.2d\n",dir[dir_id].ctime.wYear,dir[dir_id].ctime.wMonth,dir[dir_id].ctime.wDay,dir[dir_id].ctime.wHour,dir[dir_id].ctime.wMinute,dir[dir_id].ctime.wSecond);
}

void show_file(int file_id)                        //显示一个文件
{
	printf("%s",file[file_id].file_name);
	for(int i=strlen(file[file_id].file_name);i<20;i++)
		printf(" ");
	printf("<FILE>");
	for(i=26;i<30;i++)
		printf(" ");
	printf("%d-%.2d-%.2d %.2d:%.2d:%.2d",file[file_id].ctime.wYear,file[file_id].ctime.wMonth,file[file_id].ctime.wDay,file[file_id].ctime.wHour,file[file_id].ctime.wMinute,file[file_id].ctime.wSecond);
	for(i=0;i<8;i++)
		printf(" ");
	int length=file[file_id].file_length;
	if(open_files[file_id]==2)                     //如果该文件已经以写的方式被打开,则需改变
	{
		int buf_id=get_buffer_id(file_id);
		length=buffer[buf_id].length;
	}
	printf("len: %d bytes\n",length);
}

void show(int dir_id)                              //显示目录及文件的核心函数,用了递归思想                         
{
	for(int i=0;i<dir[dir_id].file_count;i++)
		show_file(dir[dir_id].child_file[i]);
	for(i=0;i<dir[dir_id].dir_count;i++)
		show_dir(dir[dir_id].child_dir[i]);
}

void list()                                        //显示文件及目录的主调函数
{ 
	show(curr);                                    //该函数的参数表示根目录的索引
	printf("\n%d files.\n",curr_dir->file_count);  //统计文件数
	printf("\n%d dirs.\n",curr_dir->dir_count);    //统计目录数
}

void write_bit(int pos,int type)                   //写回目录节点、文件节点或磁盘块的占用标志
{                                                  //type为0时,写目录;
	if(type==0)                                    //type为1时,写文件;
	{                                              //type为2时,写磁盘块
		fseek(fp,sizeof(int)*(pos+3),SEEK_SET);    //该函数只有在创建和删除时才调用
		fwrite(&dir_flag[pos],sizeof(int),1,fp);
	}
	else if(type==1)
	{
		fseek(fp,sizeof(int)*(DIR_NUM+pos+3),SEEK_SET);
		fwrite(&file_flag[pos],sizeof(int),1,fp);
	}
	else
	{		
		fseek(fp,sizeof(int)*(DIR_NUM+FILE_NUM+pos+3),SEEK_SET);
		fwrite(&block_flag[pos],sizeof(int),1,fp);
	}
}

void write_inode(int pos,int type)                 //写回目录或文件节点的控制信息        
{                                                  //type为0时,写目录;
	if(type==0)                                    //type为1时,写文件;
	{                                              //有目录或文件的控制信息被修改,该函数就被调用
		fseek(fp,sizeof(int)*(DIR_NUM+FILE_NUM+BLOCK_NUM+3)+sizeof(struct dir_node)*pos,SEEK_SET);
		fwrite(&dir[pos],sizeof(struct dir_node),1,fp);
	}
	else
	{
		fseek(fp,sizeof(int)*(DIR_NUM+FILE_NUM+BLOCK_NUM+3)+sizeof(struct dir_node)*DIR_NUM+sizeof(struct file_node)*pos,SEEK_SET);
		fwrite(&file[pos],sizeof(struct file_node),1,fp);
	}
}

void write_disk(int i,int j)                       //将缓冲区内的数据写回磁盘,这个函数较复杂
{                                                  //首先确定写的开始位置
	int write_start=(file[i].file_length<buffer[j].offset)?file[i].file_length:buffer[j].offset;
	file[i].file_length=buffer[j].length;
	al_file[i]++;
	int block_start=write_start/BLOCK_SIZE;
	int block_offset=write_start%BLOCK_SIZE;
	int length=buffer[j].length-write_start;
	int extra=buffer[j].length%BLOCK_SIZE;

	fseek(fp,sizeof(int)*(DIR_NUM+FILE_NUM+BLOCK_NUM+3)+sizeof(struct dir_node)*DIR_NUM+sizeof(struct file_node)*FILE_NUM+file[i].block[block_start]*BLOCK_SIZE+block_offset,SEEK_SET);					
	fwrite(buffer[j].buf+write_start,BLOCK_SIZE-block_offset,1,fp);
	for(int k=block_start+1;k<file[i].block_count-1;k++)			
	{					
		fseek(fp,sizeof(int)*(DIR_NUM+FILE_NUM+BLOCK_NUM+3)+sizeof(struct dir_node)*DIR_NUM+sizeof(struct file_node)*FILE_NUM+file[i].block[k]*BLOCK_SIZE,SEEK_SET);					
		fwrite(buffer[j].buf+BLOCK_SIZE*k,BLOCK_SIZE,1,fp);
	}                        
	if(extra>0 && length>BLOCK_SIZE)                       
	{					        
		fseek(fp,sizeof(int)*(DIR_NUM+FILE_NUM+BLOCK_NUM+3)+sizeof(struct dir_node)*DIR_NUM+sizeof(struct file_node)*FILE_NUM+file[i].block[k]*BLOCK_SIZE,SEEK_SET);					        
		fwrite(buffer[j].buf+BLOCK_SIZE*k,extra,1,fp);                        
	}
}

void savefile(int file_id)                         //显式保存文件的核心函数
{
	if(open_files[file_id]>0)                      //如果占用缓冲区,应该释放                     
	{
		int buf_id=get_buffer_id(file_id);
		if(open_files[file_id]==2)                 //如果该文件以写的方式被打开,应先将其数据
			write_disk(file_id,buf_id);            //写回磁盘
		buffer[buf_id].flag=0;		
		open_files[file_id]=0;
	}
	if(al_fflag[file_id]%2!=0)                     //如果创建或删除,需要写回磁盘	
	{					
		write_bit(file_id,1);		
		al_fflag[file_id]=0;	
	}
	if(al_file[file_id]>0)                         //如果控制信息被修改,需要写回磁盘
	{	
		write_inode(file_id,1);	
		al_file[file_id]=0;
		for(int i=0;i<file[file_id].block_count;i++)		
		{			
			int temp=file[file_id].block[i];			
			if(al_bflag[temp]%2!=0)                //如果磁盘块被释放或被占用,需要写回磁盘			
			{				
				write_bit(temp,2);				
				al_bflag[temp]=0;
			}
		}
	}
}

void save_dir(int dir_id)                          //保存空目录函数
{
	if(al_dflag[dir_id]%2!=0)                      //如果删除或创建,需要写回磁盘	
	{		
		write_bit(dir_id,0);			
		al_dflag[dir_id]=0;	
	}
	if(al_dir[dir_id]>0)                           //如果控制信息被修改,需要写回磁盘		
	{
		write_inode(dir_id,0);		
		al_dir[dir_id]=0;
	}
}

void savedir(int dir_id)                           //保存一个目录,及它的所有父目录,用了递归
{
	if(dir_id==-1)
		return;
	save_dir(dir_id);
	savedir(dir[dir_id].parent);
}

void save(int dir_id)                              //保存一个目录及它下面的所有目录及文件
{                                                  //用了递归
	for(int i=0;i<dir[dir_id].dir_count;i++)
		save(dir[dir_id].child_dir[i]);
	for(i=0;i<dir[dir_id].file_count;i++)
		savefile(dir[dir_id].child_file[i]);
	save_dir(dir_id);
}

int save_file(int parent,char *file_name)          //显式保存文件
{
	int pos,index;
	if((pos=search(parent,file_name,1,index))==-1)
	{
		printf("The file not exist in current directory!\n");
		return -1;
	}
	savedir(parent);                               //保存父目录
	savefile(pos);
	return pos;
}

int savefile(char *name)                           //保存文件的主调函数                        
{
	int parent,p=0;
	parent=get_parent(name,p);

⌨️ 快捷键说明

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