📄 mydisk.cpp
字号:
// 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 + -