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

📄 mydisk.cpp

📁 申请一个10M的文件空间虚拟成一个磁盘
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// disk.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
  char name[13];             //文件名//
  int startblock;            //起始块//
  unsigned long size;        //文件大小//
  int status;                //目录状态// 
}FCB;
typedef struct
{
	unsigned long disksize;  //磁盘大小//
    unsigned int blocksize;  //块长//
    unsigned int blocks;     //总块数//
	unsigned int FATblocks;  //FAT块数1-32//
    unsigned int dirblocks;  //目录区块数33-34 //
	unsigned int datablocks; //文件数据区块数//
    unsigned int idleblocks; //空闲块数//
    unsigned int files;      //文件数//
    unsigned long freesize;  //可用空间//
    unsigned int realfiles;  //有效文件数//
	unsigned int fcbsnum;    //最大目录数//
}DISK;
typedef struct
{
	int fats;               //FAT表//
}FAT;
typedef struct
{
	DISK disk;
    FCB *fcbs;
    FAT *fat;
}DISKINFO;

FILE *Format(FILE *fp,unsigned long disksize)//格式化虚拟磁盘//
{
	char *data;
	DISKINFO *disk;
	unsigned int i;
	disk=(DISKINFO*)malloc(sizeof(DISKINFO));
	disk->disk.disksize=disksize;
	disk->disk.blocksize=4096; //块长4K//
	disk->disk.blocks=disk->disk.disksize/disk->disk.blocksize;
	disk->disk.FATblocks=32;   
	disk->disk.dirblocks=2;
	disk->disk.datablocks=disk->disk.blocks-disk->disk.FATblocks-disk->disk.dirblocks-1;//文件数据块数//
	disk->disk.idleblocks=disk->disk.blocks-disk->disk.FATblocks-disk->disk.dirblocks-1;//空闲块数//
	disk->disk.files=0;
	disk->disk.freesize=disk->disk.blocksize*disk->disk.idleblocks;
	disk->disk.realfiles=0;
	disk->disk.fcbsnum=320;
	disk->fat=(FAT*)malloc(disk->disk.datablocks*sizeof(FAT));
	for(i=0;i<disk->disk.datablocks;i++)   //初始化FAT表//
	{
		(disk->fat+i)->fats=0;
	}
	data=(char *)malloc(disk->disk.blocksize);
	fseek(fp,0,0);
	for(i=0;i<disk->disk.blocks;i++)     //向磁盘写入空数据,使其达到预定大小//
		fwrite(data,disk->disk.blocksize,1,fp);
	fseek(fp,0,0);                           //向磁盘写入DISKINFO信息//
	fwrite(&disk->disk,sizeof(DISK),1,fp);
	fseek(fp,disk->disk.disksize,0);
	fwrite(disk->fat,disk->disk.datablocks*sizeof(disk->fat),1,fp);
	disk->fcbs=(FCB*)malloc(disk->disk.fcbsnum*sizeof(FCB));
	for(i=0;i<disk->disk.fcbsnum;i++)
		(disk->fcbs+i)->status=0;
	fseek(fp,disk->disk.blocksize*(1+disk->disk.FATblocks),0);
	fwrite(disk->fcbs,disk->disk.fcbsnum*sizeof(FCB),1,fp);
	free(data);
	free(disk->fat);
	free(disk->fcbs);
	return(fp);
};
FILE *Bulid()         //建立新磁盘//
{
	FILE *fp=NULL;
	char name[13];
	char c;
	unsigned int t;
	unsigned long disksize;
	while(1)
	{
		printf("Please enter the disk's name:");
	    scanf("%s",name);
		getchar();
	    if((fp=fopen(name,"rb+"))!=NULL)      //判断是否有同名的文件存在//
		{
			printf("磁盘已存在.是否覆盖?(Y/N):");
		    scanf("%c",&c);
			getchar();
		    if(c=='N'||c=='n')
			{
				printf("是否使用%s磁盘?(Y/N):",name);
			    scanf("%c",&c);
				getchar();
			    if(c=='Y'||c=='y')break;
			    else continue;
		    }
			else if(c!='Y'&&c!='y')
			{
				printf("Error!\n");
				continue;
			}
	    }
	    printf("Please enter the disk size(MB):");
	    scanf("%d",&t);
		getchar();
		if(t<1||t>128)
		{
			printf("本系统只支持1~128MB的虚拟磁盘,请重新输入.\n");
			continue;
		}
	    disksize=1048576l*t;
		fp=fopen(name,"wb+");
	    fp=Format(fp,disksize);
	    break;
	}
	return(fp);
};
FILE *load()   //载入磁盘//
{
	FILE *fp=NULL;
	char name[13];
    printf("please enter the disk name:");
	scanf("%s",name);
	getchar();
	fp=fopen(name,"rb+");                      //打开虚拟磁盘文件//
	if(fp==NULL)printf("Disk not found\n");
	return(fp);
};
void help()   //显示帮助//
{
	printf("欢迎使用虚拟文件系统  V1.0\n作者:沈伟宏\n本系统采用单级目录FAT方案,可采用2种方式启动本程序:\n1.disk.exe\n2.disk.exe 虚拟磁盘名称\n\n");
	printf("本系统支持以下命令:\n");
	printf(" cat      显示文件内容\n");
	printf(" copy     虚拟磁盘内拷贝\n");
	printf(" del      删除文件\n");
	printf(" dir      显示文件信息\n");
	printf(" exit     退出\n");
	printf(" fatinfo  显示FAT表信息\n");
	printf(" format   格式化虚拟磁盘\n");
	printf(" help     显示帮助\n");
	printf(" icopy    真实磁盘向虚拟磁盘拷贝\n");
	printf(" ocopy    虚拟磁盘向真实磁盘拷贝\n");
	printf(" rename   文件重命名\n");
	printf(" showdisk 显示虚拟磁盘信息\n");
	printf("\n");	
};
FILE *Select() 
{
    char select;
	FILE *fp=NULL;
	while(1)
	{
		printf("Please choose operate:\n 1.load\n 2.Bulid a new disk\n 3.Help\n 4.Exit\nEnter the number:");
		select=getchar();
		getchar();
		if(select=='1')
		{
			fp=load();   //载入已有磁盘//
		}
		else if(select=='2')
		{
			fp=Bulid();  //新建一个虚拟磁盘//
		}
		else if(select=='3')
		{
			help();       //显示帮助//
		}
		else if(select=='4')
		{
			exit(0);      //推出管理程序//
		}
		if(fp!=NULL)
		{
			break;
		}
	}
	return(fp);
};
int del(DISKINFO *disk,char *name)  //删除文件//
{
	unsigned int m;
	unsigned int k,n;
	for(m=0;m<disk->disk.fcbsnum;m++)             //判断文件是否存在//
	{
		if((disk->fcbs+m)->status==1&&(strcmp((disk->fcbs+m)->name,name)==0))
			break;
	}
	if(m>=disk->disk.fcbsnum)
	{
		printf("文件不存在.\n");
		return(-1);
	}
	if((disk->fcbs+m)->size==0)                //判断要删除的文件是否为空//
	{
		(disk->fcbs+m)->status=0;             //修改FCB//
		(disk->fcbs+m)->startblock=0;
		disk->disk.files--; 
		return(0);
	}
	k=(disk->fcbs+m)->startblock;
	while((disk->fat+k)->fats!=-1)           //修改FAT//
	{
		n=(disk->fat+k)->fats;
		(disk->fat+k)->fats=0;
		k=n;
	}
	(disk->fat+k)->fats=0;                  //修改盘卷总信息//
	(disk->fcbs+m)->startblock=0;
	(disk->fcbs+m)->status=0;
	disk->disk.freesize+=(disk->fcbs+m)->size;
	disk->disk.idleblocks+=((disk->fcbs+m)->size/disk->disk.blocksize+(1&&(disk->fcbs+m)->size%disk->disk.blocksize));
	disk->disk.files--;
	disk->disk.realfiles--;
	return(0);
};
//虚拟磁盘向外拷贝//
int ocopy(DISKINFO *disk,FILE *fp,char *name1,char *name2)//文件指针,要复制的文件名,目的文件名//
{
	unsigned int m;
	unsigned int k;
	int lastblock;
	FILE *file;
	char *data;
	char t;
	if(name1[0]=='\0')
	{
		printf("命令格式错误.\n");
		return(-1);
	}
	if(name2[0]=='\0')
		strcpy(name2,name1);
	for(m=0;m<disk->disk.fcbsnum;m++)  //寻找文件//
		if((disk->fcbs+m)->status==1&&(strcmp((disk->fcbs+m)->name,name1))==0)
			break;
	if(m>=disk->disk.fcbsnum)
	{
		printf("文件不存在.\n");
		return(-1);
	}; 
	if((file=fopen(name2,"r"))!=NULL)//判断真实磁盘上是否有同名文件存在//
	{
		printf("文件%s已存在,是否替换(Y/N)?",name2);
		scanf("%c",&t);
		getchar();
		if(t!='y'&&t!='Y')
		{
			fclose(file);
			printf("文件%s已存在,复制失败.\n",name2);
			return(-1);
		}
	}
	
	file=fopen(name2,"wb");  //在真实磁盘上建立新文件//
	if((disk->fcbs+m)->size==0)
	{
		printf("文件复制成功,大小为0B.\n");
		return(0);
	}
	data=(char*)malloc(disk->disk.blocksize);
	k=(disk->fcbs+m)->startblock;
	lastblock=(disk->fcbs+m)->size%disk->disk.blocksize;
	fseek(file,0,0);
	while((disk->fat+k)->fats!=-1)  //读取,写入//
	{
		fseek(fp,(1+disk->disk.FATblocks+disk->disk.dirblocks+k)*disk->disk.blocksize,0);
		fread(data,disk->disk.blocksize,1,fp);
		fwrite(data,disk->disk.blocksize,1,file);
		k=(disk->fat+k)->fats;
	}
	if((lastblock)!=0)  //写入最后一块//
	{
		fseek(fp,(1+disk->disk.FATblocks+disk->disk.dirblocks+k)*disk->disk.blocksize,0);
		fread(data,lastblock,1,fp);
	    fwrite(data,lastblock,1,file);
	}
	else
	{
		fseek(fp,(1+disk->disk.FATblocks+disk->disk.dirblocks+k)*disk->disk.blocksize,0);
		fread(data,disk->disk.blocksize,1,fp);
		fwrite(data,disk->disk.blocksize,1,file);
	}
	fclose(file);
	free(data);
	printf("一个文件拷贝成功.\n");
	fclose(file);
	return(0);
};  
//真实磁盘向虚拟磁盘拷贝//
int icopy(DISKINFO *disk,FILE *fp,char *name1,char *name2)//文件指针,要复制的文件名,目的文件名//
{
	unsigned int m;
	unsigned int i;
	unsigned int k;
	unsigned int n;
	unsigned int fileblocks;
	unsigned long filesize;
	int lastblock;
	FILE *file;
	char *data;
	char t;
	data=(char *)malloc(disk->disk.blocksize);
	if(name1[0]=='\0')
	{
		printf("命令格式错误.\n");
		return(-1);
	}
	if((file=fopen(name1,"rb"))==NULL)  //能否打开文件//
	{
		printf("文件%s不存在.\n",name1);
		return(-1);
	}
	if(name2[0]=='\0')
		strcpy(name2,name1);
	for(i=0;i<disk->disk.fcbsnum;i++)             //判断虚拟磁盘上是否有同名文件存在//
	{
		if((disk->fcbs+i)->status==1&&(strcmp((disk->fcbs+i)->name,name2)==0))
		{
			printf("文件%s已存在,是否替换(Y/N)?",name2);
			scanf("%c",&t);
			getchar();
			if(t!='y'&&t!='Y')
			{
				printf("文件%s已存在,复制失败.\n",name2);
				return(-1);
			}
			else 
			{
				del(disk,name2);
				break;
			}
		}
	}
	if(disk->disk.files>=disk->disk.fcbsnum)   //判断目录是否已满//
	{
		printf("目录已满,操作无法完成.\n");
		return(-1);
	}
	else                        //找到空目录m//
	{
		for(m=0;m<=disk->disk.fcbsnum;m++)
		{
			if((disk->fcbs+m)->status==0)
				break;
		}
	}
	fseek(file,0,2);
	filesize=ftell(file);
	if(filesize==0)                 //复制空文件//
	{
		disk->disk.files++;
		(disk->fcbs+m)->status=1;
		(disk->fcbs+m)->startblock=-1;
		(disk->fcbs+m)->size=0;
		strcpy((disk->fcbs+m)->name,name2);
		printf("复制成功,文件大小为0B.\n");
		return(0);
	}
	if(disk->disk.freesize<filesize)  //判断是否有足够空间//
	{
		printf("可用空间不足.\n");
		fclose(file);
		return(-1);
	}
	lastblock=filesize%disk->disk.blocksize;
	fileblocks=filesize/disk->disk.blocksize+(lastblock&&1);
	(disk->fcbs+m)->size=filesize;
	(disk->fcbs+m)->status=1;
	strcpy((disk->fcbs+m)->name,name2);
	fseek(file,0,0);
	for(i=1;i<fileblocks;i++)              //写入前n-1块//
	{
		for(k=1;k<disk->disk.datablocks;k++)//寻找空闲块K//
		{
			if((disk->fat+k)->fats==0)
				break;
		}
	    if(i==1)
	    {(disk->fcbs+m)->startblock=k;}
	    else
	    {(disk->fat+n)->fats=k;}
	    fread(data,disk->disk.blocksize,1,file);   //读取第i块,写如虚拟磁盘第K块//
	    fseek(fp,(1+disk->disk.FATblocks+disk->disk.dirblocks+k)*disk->disk.blocksize,0);
	    fwrite(data,disk->disk.blocksize,1,fp);
		(disk->fat+k)->fats=-1;
	    n=k;
    }
	
	for(k=1;k<disk->disk.datablocks;k++)//寻找空闲块K//
	{
		if((disk->fat+k)->fats==0)
			break;
	}
	if(lastblock==0)  //写入最后一块//
	{

⌨️ 快捷键说明

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