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

📄 myfs.txt

📁 这是我写的一个用于测试的文件系统
💻 TXT
📖 第 1 页 / 共 4 页
字号:
#include<stdio.h>                          
#include<stdlib.h>
#include<conio.h>
#include<string.h>
#include<iostream.h>
#include<windows.h>

#define BLOCK_SIZE 512                             //磁盘块大小                  
#define DIR_NUM 64                                 //最多目录节点数                      
#define FILE_NUM 512                               //最多文件节点数
#define BLOCK_NUM 1024                             //磁盘块数目
#define BUF_NUM 32                                 //主存缓冲区数目

const char file_system_name[]="fs.dat";            //磁盘文件名 

struct dir_node                                    //目录节点                     
{
	char space;
	SYSTEMTIME ctime;                              //创建时间
	char dir_name[32];                             //目录名                   
	int child_dir[8];                              //子目录索引                 
	int dir_count;                                 //当前子目录数                     
	int child_file[16];                            //子文件索引              
	int file_count;                                //当前子文件数
	int parent;                                    //父目录索引
};

struct file_node                                   //文件节点
{
	char space;
	SYSTEMTIME ctime;                              //创建时间
	char file_name[32];                            //文件名                
	int block[4];                                  //该文件占有的磁盘块索引
	int block_count;                               //该文件当前占有的磁盘块数
	int file_length;                               //文件长度                  
	int parent;                                    //父目录索引
};

struct buffer_node                                 //主存缓冲区节点                      
{
	int flag;                                      //占用标志                              
	int file_id;                                   //占用该缓冲区节点的文件索引                    
	char buf[BLOCK_SIZE*4];                        //缓冲区,存放读写文件的数据          
	int length;                                    //缓冲区大小                                          
	int offset;                                    //打开系统后第一次写该文件的开始位置
};

struct dir_node dir[DIR_NUM+1];                    //目录节点表              
struct file_node file[FILE_NUM];                   //文件节点表       
struct buffer_node buffer[BUF_NUM];                //缓冲区数组    

int dir_flag[DIR_NUM];                             //各目录节点占用标志,0表示空闲,1表示被占用
int used_dir;                                      //已用的目录节点数
int file_flag[FILE_NUM];                           //各文件节点的占用标志
int used_file;                                     //已用的文件节点数
int block_flag[BLOCK_NUM];                         //磁盘块的占用标志           
int used_block;                                    //已用的磁盘块数

int al_dir[DIR_NUM];                               //目录节点修改登记表                  
int al_file[FILE_NUM];                             //文件节点修改登记表                   

int al_dflag[DIR_NUM];                             //目录节点占用标志登记表
int al_fflag[FILE_NUM];                            //文件节点占用标志登记表
int al_bflag[BLOCK_NUM];                           //磁盘块占用标志登记表            

int open_files[FILE_NUM];                          //文件读写登记表                 

int curr;                                          //当前目录索引                                 
struct dir_node *curr_dir;                         //当前目录节点指针     
char curr_path[512];                               //当前路径              

FILE *fp;                                          //文件指针                                 

int f_count;                                       //用于计算被复制目录下的文件数目
int d_count;                                       //用于计算被复制目录下的子目录数目
int b_count;                                       //用于计算被复制目录下的文件占用的磁盘块数目

void create_file_system()                          //创建文件系统              
{
	fp=fopen(file_system_name,"wb+");              //以读写方式打开,如果存在,则覆盖原来信息,
	if(fp==NULL)                                   //否则创建该文件    
	{
		printf("Create file system error!\n");
		exit(1);
	}
                                                   //申请空间
	int total=sizeof(int)*(DIR_NUM+FILE_NUM+BLOCK_NUM+3)+sizeof(struct dir_node)*DIR_NUM+sizeof(struct file_node)*FILE_NUM+BLOCK_SIZE*BLOCK_NUM;
	for(long len=0;len<total;len++)
		fputc(0,fp);

	fseek(fp,0,SEEK_SET);                          //写超级块信息
	used_dir=1;
	fwrite(&used_dir,sizeof(int),1,fp);	
	used_file=0;
	used_block=0;
	fwrite(&used_file,sizeof(int),2,fp);
	dir_flag[0]=1;
	fwrite(&dir_flag[0],sizeof(int),1,fp);         //标志对应目录节点、文件节点的使用情况
	fwrite(&dir_flag[1],sizeof(int),DIR_NUM+FILE_NUM+BLOCK_NUM-1,fp);

	strcpy(dir[0].dir_name,"A:");                  //写根目录信息
	dir[0].dir_count=0;
	dir[0].file_count=0;
	dir[0].parent=-1;
	GetLocalTime(&dir[0].ctime);                   //获得当前时间
	fwrite(&dir[0],sizeof(struct dir_node),1,fp);
                                                   
	for(int i=0;i<DIR_NUM;i++)                     //将所有标记清零
	{
		al_dir[i]=0;
		al_dflag[i]=0;
		dir[i].dir_count=0;
		dir[i].file_count=0;
	}
	for(i=0;i<FILE_NUM;i++)                
	{
		al_file[i]=0;
		al_fflag[i]=0;
		open_files[i]=0;
	}
	for(i=0;i<BLOCK_NUM;i++)                
		al_bflag[i]=0;

	for(i=0;i<BUF_NUM;i++)
		buffer[i].flag=0;

	fflush(fp);
	fclose(fp);
}

int search(int parent,char *name,int type,int &index)  //搜索目录或文件,成功则返回该文件或目录的索引
{                                                  //失败则返回-1,type用来区分要搜索的是文件还是目录    
	struct dir_node *p=&dir[parent];               //0表示目录,1表示文件,index用来指定找到的文件或
	int i,temp;                                    //目录在父目录下的位置
	if(type==0)                                                    
		for(i=0;i<p->dir_count;i++)
		{
			temp=p->child_dir[i];
			if(strcmp(name,dir[temp].dir_name)==0)
			{
				index=i;
				return temp;
			}
		}
	else
		for(i=0;i<p->file_count;i++)
		{
			temp=p->child_file[i];
			if(strcmp(name,file[temp].file_name)==0)
			{
				index=i;
				return temp;
			}
		}

	return -1;
}

int get_parent(char *name,int &p)                  //根据输入的字符串,获得父目录及真正的文件
{                                                  //或目录名,引用参数p用来指定目录或文件名
	char buf[32],*path,*s;                         //的起始位置
	int pos,start=0,index;
	path=new char[128];
	strcpy(path,name);

	s=strrchr(path,'/');                           //如果没有指定路径,则将当前目录指定为
	if(s==NULL)                                    //父目录
		return curr;

	pos=(int)(s-path);
	p=pos+1;
	if(p==(int)strlen(path))
		return -1;
	path[p]='\0';
	
	s=strchr(path,'/');
	pos=(int)(s-path);
	if(strncmp(path,"A:",pos)!=0)                  //前面没有跟目录名,则从当前目录往下搜索
		start=curr;
	else	
		path+=3;
	while(start!=-1 && (int)strlen(path)>0)        //进行搜索,知道路径名结束或出现不匹配
	{
		s=strchr(path,'/');
		pos=(int)(s-path);
		strncpy(buf,path,pos);
		buf[pos]='\0';
		start=search(start,buf,0,index);
		path+=pos+1;
	}
	return start;                                 
}                                                  

int get_block(int pos)                             //为文件申请磁盘块,一次调用申请一块,成功则返回                      
{                                                  //磁盘块索引,失败返回-1
	for(int i=0;i<BLOCK_NUM;i++)
		if(block_flag[i]==0)
		{                                          //修改磁盘块使用情况及文件的控制信息
			block_flag[i]=1;
			al_bflag[i]++;
			used_block++;
			int top=file[pos].block_count;
			file[pos].block[top]=i;
			file[pos].block_count++;
			return i;
		}
	return -1;
}

void return_block(int pos)                         //释放文件占用的磁盘块,用于删除文件时用
{
	for(int i=0;i<file[pos].block_count;i++)
	{
		int temp=file[pos].block[i];
		block_flag[temp]=0;
		al_bflag[temp]++;
	}
	used_block-=file[pos].block_count;
}

int get_dir(int parent,char *dir_name)             //创建目录节点,成功则返回目录的索引,失败则返回-1
{
	int index;
	if(search(parent,dir_name,0,index)!=-1)        //搜索在父目录下是否有同名目录,有则创建失败        
	{
		printf("Directory name repeated!\n");
		return -1;
	}
	for(int i=1;i<DIR_NUM;i++)                     //搜索空闲的目录节点           
		if(dir_flag[i]==0)
		{                                          //登记并给目录节点初始化
			dir_flag[i]=1; 
			al_dflag[i]++;
			al_dir[i]++;
			used_dir++;
			strcpy(dir[i].dir_name,dir_name);
			dir[i].dir_count=0;
			dir[i].file_count=0;
			dir[i].parent=parent;
			GetLocalTime(&dir[i].ctime);           //获得当前时间
			return i;
		}
	return -1;
}

int get_file(int parent,char *file_name)           //创建文件节点,成功则返回文件的索引号,失败返回-1
{
	int index;
	if(search(parent,file_name,1,index)!=-1)       //搜索在父目录下是否有同名文件存在,有则创建失败
	{
		printf("File name repeated!\n");
		return -1;
	}
	for(int i=0;i<FILE_NUM;i++)                    //搜索空闲的文件节点             
		if(file_flag[i]==0)
		{
			strcpy(file[i].file_name,file_name);
			file[i].block_count=0;
			if(get_block(i)==-1)                   //给新创建的文件申请磁盘块,如果失败,创建文件           
			{                                      //将失败
				printf("Disk volumn error!\n");
				return -1;
			}
			file_flag[i]=1;
			al_fflag[i]++;                         //登记并给文件节点初始化
			al_file[i]++;
			used_file++;
			file[i].file_length=0;
			file[i].parent=parent;
			GetLocalTime(&file[i].ctime);          //获得当前时间
			return i; 
		}
	return -1;
}

int get_buffer(int pos)                            //给文件申请缓冲区,打开文件时调用,失败时返回-1
{
	for(int i=0;i<BUF_NUM;i++)
		if(buffer[i].flag==0)
		{
			buffer[i].flag=1;                      //修改使用标志并初始化
			buffer[i].file_id=pos;
			buffer[i].length=0;
			buffer[i].offset=0;
			return i;
		}
	return -1;
}

int get_buffer_id(int pos)                         //得到被打开文件的缓冲区索引号,失败则返回-1
{
	for(int i=0;i<BUF_NUM;i++)
		if(buffer[i].flag==1 && buffer[i].file_id==pos)
			return i;
	return -1;
}

int create_file(int parent,char *file_name)        //在指定的目录下创建文件,如果创建成功则返回  
{                                                  //文件的索引号,否则返回-1
	if(dir[parent].file_count==16)                 //如果父目录已满,则创建失败
	{
		printf("Parent directory is full!\n");
		return -1;
	}					
	int pos=get_file(parent,file_name);            //开始创建文件
	if(pos==-1)
	{
		printf("Create file error!\n");
		return -1;
	}
                                           
	struct dir_node *p=&dir[parent];               //修改父目录的控制信息
	int top=p->file_count;              
	p->child_file[top]=pos;
	p->file_count++;
	al_dir[parent]++;

	return pos;
}

int create_dir(int parent,char *dir_name)          //在指定的目录下创建目录,如果成功则返回目录        
{                                                  //的索引号,否则返回-1
	if(dir[parent].dir_count==8)                   //如果父目录已满,则创建失败
	{
		printf("Parent directory is full!\n");
		return -1;
	}
	int pos=get_dir(parent,dir_name);              //开始创建目录
	if(pos==-1)
	{
		printf("Create directory error!\n");
		return -1;
	}

	struct dir_node *p=&dir[parent];               //修改父目录的控制信息
	int top=p->dir_count;         
	p->child_dir[top]=pos;
	p->dir_count++;
	al_dir[parent]++;

	return pos;
}

int md(char *name)                                 //创建目录的主调函数,它的参数只有用户输入
{                                                  //如果创建成功,则返回目录的索引号,否则
	int parent,p=0;                                //返回-1
	parent=get_parent(name,p);
	if(parent==-1)                                 //父目录找不到,输入有误,创建失败
	{
		printf("Path name error!\n");
		return -1;
	}
	return create_dir(parent,name+p);              //开始创建目录
}

int rename_dir(char *old_name,char *new_name)      //对目录重命名,需要输入两个参数,如果
{                                                  //成功返回目录的索引号,否则返回-1
	int parent,p=0,index;
	parent=get_parent(old_name,p);
	if(parent==-1)                                 //找不到父目录,输入错误,重命名失败                               
	{
		printf("Path name error!\n");
		return -1;
	}
	int dir_id=search(parent,old_name+p,0,index);  //找到父目录,查找要重命名的目录
	if(dir_id==-1)                                 //找不到该目录,重命名失败
	{
		printf("The directory not exist!\n");
		return -1;
	}
	if(strcmp(old_name+p,new_name)!=0 && search(parent,new_name,0,index)!=-1)
	{                                              //重命名后出现目录重名,重命名失败
		printf("Dir name repeated!\n");
		return -1;
	}
	strcpy(dir[dir_id].dir_name,new_name);
	al_dir[dir_id]++;
	return dir_id;
}

int create(char *name)                             //创建文件的主调函数,直接接受用户输入
{                                                  //成功返回文件的索引号,否则返回-1
	int parent,p=0;
	parent=get_parent(name,p);
	if(parent==-1)                                 //找不到父目录,输入错误,创建失败
	{
		printf("Path name error!\n");
		return -1;
	}
	return create_file(parent,name+p);             //开始创建文件
}

int rename_file(char *old_name,char *new_name)     //对文件重命名,成功返回文件的索引号

⌨️ 快捷键说明

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