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

📄 filesystem.cpp

📁 文件fat系统的实现在内存中的一种模拟方式
💻 CPP
字号:
#include "precomp.h"


u_char  g_disk[MAX_DISK_SIZE];//用内存模拟的磁盘空间
const int	g_freedisksize = MAX_DISK_SIZE;	//虚拟磁盘的空闲空间
const char	g_freeflag = (char)0xE5;

/********************************************************************
获取指定块的首地址
	blockno :指定模拟磁盘块号
	所以FAT表的首地址为getBlockAddr(0);
	目录的首地址为getBlockAddr(1);
*********************************************************************/
void* getBlockAddr(int blockno)
{
	return (g_disk + blockno * BLOCKSIZE);
}

//初始化虚拟磁盘空间
void InitDisk()
{
	PFCB pFCB = NULL;

	memset(g_disk,0,MAX_DISK_SIZE);
	
	for (int i=1 ; i <= 4 ; i++)	//4个目录项置为空闲
	{
		pFCB = (PFCB)getBlockAddr(i);
		pFCB->f_name[0] = g_freeflag;
	}
	
	for (int j=0 ; j <= 4 ; j++)	//FAT表的前5字节置FF,表示已被占用
	{
		((PFAT)(g_disk+j))->cluster = (u_char)0xFF;
	}
}



/********************************************************************
创建文件
	f_name : 文件名指针
	f_content : 文件的内容指针
	f_size : 文件长度
返回值:
	0:正常
	10:通过查找FAT表,没找到足够的块来创建文件
	11:目录项全部用完,无法增加新的文件。
		(通过检查文件名第一个字节是否为E5,是则表示空闲)
	12:链表创建出错
说明:
	
*********************************************************************/
int CreateFile(pchar f_name, pchar f_content, int f_size)
{
	PFCB pFCB = NULL; //目录项(FCB)指针
	PFAT pFAT = (PFAT)getBlockAddr(0); //FAT表的首地址
	int blockcount = 0;
	

	for (int i=1 ; i <= 4 ; i++) 
	{
		pFCB = (PFCB)getBlockAddr(i);

		if (pFCB->f_name[0] == g_freeflag)  //有空闲的目录项
		{
			blockcount = (f_size / BLOCKSIZE) + 1;
			
			///////////////////////////////////////////////////////////////
			//查找FAT,是否有足够的空闲块,使用一个链表记录要占用的空闲块号
			int k = blockcount;
			PNODE pListHead,pNode;
			
			if (initList(&pListHead) != SUCCESS)
			{
				return 12; //list initialize errno
			}

		
			for (int j=5; j < MAX_FAT ; j++)
			{
				if (((PFAT)(pFAT+j))->cluster == u_char(0))
				{
					insert(pListHead,j);
					if(--k == 0)
						break;
				}
			}
			
			if (k > 0)
				return 10;	//file size error no

			printList(pListHead);
			//*******************************************************
			
			
			
			//下面开始向块中写文件内容,同时更改目录项FCB的内容
			strcpy(pFCB->f_name,f_name);					//写文件名
			pFCB->f_size = f_size;							//写文件大小
			pFCB->f_firstblock = pListHead->pNext->iValue;	//文件起始块号

			int remainbyte = f_size; //还剩多少字节没写进块
			pNode = pListHead->pNext;

			for (k = 0 ; k < blockcount ; k++)
			{
				if (remainbyte <= BLOCKSIZE) //不足一个块
				{
					memcpy(getBlockAddr(pNode->iValue),
						f_content + (BLOCKSIZE * k),
						remainbyte);
				}
				else
				{
					memcpy(getBlockAddr(pNode->iValue),
						f_content + (BLOCKSIZE * k),
						BLOCKSIZE);

					remainbyte -= BLOCKSIZE;
				}

				pNode = pNode->pNext;
			}

			//根据文件占用的空闲块号改FAT表
			pNode = pListHead->pNext;
			while (1)
			{
				if (pNode->pNext == NULL)
				{
					((PFAT)(pFAT + pNode->iValue))->cluster = (u_char)0xFF;
					break;
				}

				((PFAT)(pFAT + pNode->iValue))->cluster = pNode->pNext->iValue;
				pNode = pNode->pNext;
			}

			//回收链表空间
			deleteList(pListHead);			

			return 0;
		}
	}

	
	return 11;//directory full error no
}

/********************************************************************
列出目录文件
	
	  无参数

返回值:
	<0:非正常(现在不会出现这种情况)
	其它值 :当前目录的文件个数
说明:
	
*********************************************************************/
int ListFile()
{
	PFCB pFCB = NULL;
	int filecount = 0; //文件记数
	int bytecount = 0; //文件大小累计
	
	printf("My file system list:\n");
	printf("----------------------------------------------\n");
	printf("filename\t\t\t filesize\n");
	printf("----------------------------------------------\n");

	for (int i=1 ; i<=4 ; i++) 
	{
		pFCB = (PFCB)getBlockAddr(i);

		if (pFCB->f_name[0] != g_freeflag)
		{
			//display file info
			filecount++;
			bytecount += pFCB->f_size;
			printf("%s\t\t\t\t %d Bytes\n",pFCB->f_name,pFCB->f_size);
		}
	}

	if (filecount == 0)
	{
		printf("no file in this system now!\n");
	}

	printf("----------------------------------------------\n");
	printf("total files : %d \t total bytes : %d Bytes \n\t\t\t remain bytes : %d Bytes\n",
			filecount,bytecount,g_freedisksize-bytecount);
	
	return filecount;
}


/********************************************************************
打印指定字节的字符
	
	  filecontent : 文件内容指针
	  size :要打印的字符长度

返回值:无

说明:
	
*********************************************************************/
void printc(pchar filecontent,int size)
{
	for(int i=0 ; i<size ; i++)
	{
		printf("%c",*filecontent);
		filecontent++;
	}
}


/********************************************************************
显示文件内容
	
	  filename : 文件名

返回值:
	0	:	执行成功
	<0	:	非正常(现在不会出现这种情况)
说明:
	
*********************************************************************/
int displayFile(pchar filename)
{
	PFCB pFCB = NULL;
	PFAT pFAT = (PFAT)getBlockAddr(0);
	int remainbytes = 0;

	for (int i=1 ; i<=4 ; i++) 
	{
		pFCB = (PFCB)getBlockAddr(i);
		
		if (!strcmp(pFCB->f_name,filename))
		{
			remainbytes = pFCB->f_size;
			
			//根据FCB中的起始块号得到文件第一块所在地
			//打印出第一块的内容
			printc((pchar)getBlockAddr(pFCB->f_firstblock),BLOCKSIZE);

			remainbytes -= BLOCKSIZE;

			//再到FAT中去找该文件后续块的块号,直到FAT中显示FF说明文件结束
			int firstblock = pFCB->f_firstblock;
			while ( ((PFAT)(pFAT+firstblock))->cluster != (u_char)0xFF ) 
			{
				//说明该文件还有后续块,跟据这个指示打印后续块内容
				printc((pchar)getBlockAddr(((PFAT)(pFAT+firstblock))->cluster),BLOCKSIZE);
				
				firstblock = ((PFAT)(pFAT+firstblock))->cluster;
				remainbytes -= BLOCKSIZE;
			}

			//打印最后一块
			printc((pchar)getBlockAddr(((PFAT)(pFAT+firstblock))->cluster),remainbytes);
			
			printf("\n");
			return 0; //执行成功		
		}
	}

	return -1;//未找到
}


/********************************************************************
删除文件
	
	  filename : 文件名

返回值:
	0	:	执行成功
	-1	:	非正常(现在不会出现这种情况)
说明:
	
		参考创建文件和显示文件的方法
*********************************************************************/
int deleteFile(pchar filename)
{
	/*
	 由你来实现!!
	 */

	printf("Based on your idea! ^_^!\n");
	
	return -1;//未找到
}

⌨️ 快捷键说明

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