#ifndef _FILE
#define _FILE
#include<stdio.h>
#include<string.h>
#include<iostream.h>
const int FILENAMELEN=20;//文件名最大长度
const int DISC=32;//存储空间(FAT表长度)
const int FILENUM=32;//文件个数
const int FDF=-2;
const int FFF=-1;
//文件信息结构
typedef struct file{
char filename[FILENAMELEN];
int filestart;
int filelen;
}fileinfo;
#endif
#include"file.h"
extern fileinfo file[FILENUM];
extern int filenum;
extern int FAT[DISC],blankspace;
void write(char *tmpname,int tmplen)
//功能:写新文件
//参数说明:
//tmpname-要写入的文件名,tmplen-要写入的文件长度
{
int last;
//复制文件名和文件块个数
strcpy(file[filenum].filename,tmpname);
file[filenum].filelen=tmplen;
//存文件
for(int i=2;i<DISC;i++)
{
if(FAT[i]==0)
{
last=file[filenum].filestart=i;//首个空闲块为文件开始块
break;
}
}
for(i=1;i<=tmplen;i++)
{ //last为上个记录的位置
for(int j=last+1;j<DISC;j++)
if(FAT[j]==0)
{
FAT[last]=j;
last=j;
break;
}
}
FAT[last]=FFF;//文件末存结束标记
blankspace-=tmplen;//改变空闲块个数
cout<<endl<<"文件 "<<filenum++<<endl;
cout<<"名称 和 大小 :"<<tmpname<<" "<<tmplen<<endl;
int p;
for(p=0;p<DISC;p++)
{
cout<<FAT[p]<<endl;
}
}
void cover(char *tmpname,int tmplen)
//功能:覆盖写文件
//参数说明:
//tmpname-要覆盖的文件名,tmplen-要写入的文件长度
{
int last,end,w;
//寻找要覆盖的文件,将其数组下标存入last
for(int i=0;i<filenum;i++)
{
if(strcmp(file[i].filename,tmpname)==0) last=i;
break;
}
//若要写入文件长度小于原文件长度
if(file[last].filelen>tmplen)
{ //寻找结束位
for(int i=0;i<(tmplen+2);i++)
end=FAT[i];
FAT[end]=FFF;
//逐位置零
for(int w=FAT[end+1];FAT[w]!=FFF;w++)
{
FAT[w]=0;
}
FAT[w]=0;
for(int r=0;r<DISC;r++)
{
cout<<FAT[r]<<endl;
}
}
//若要写入文件长度大于原文件长度
else if(file[last].filelen<tmplen)
{
//写入前判断是否有足够空间
if(tmplen>blankspace-file[last].filelen)
{
cout<<"没有足够的空间!"<<endl;
return;
}
//寻找原结束标记,存入end
for(int end=file[last].filestart;FAT[end]!=FFF;end=FAT[end]);
//从结束位开始,寻找空闲块存入文件
for(int i=0;i<tmplen-file[last].filelen;i++)
for(int j=0;j<DISC;j++)
if(FAT[j]==0)//块空闲则插入
{
FAT[end]=j;
end=j;
}
FAT[end]=FFF;
}
//改变空闲块个数与文件长度
blankspace-=file[last].filelen-tmplen;
file[last].filelen=tmplen;
cout<<endl<<"文件 "<<(filenum-1)<<endl;
cout<<"名称 和 大小 :"<<tmpname<<" "<<tmplen<<endl;
}
void insert(char *tmpname,int insertpoint)
//功能:在文件指定位置插入一个块
//参数说明:
//tmpname-要执行插入操作的文件名,insertpoint要插入块的位置
{
int last,brpoint;
//寻找要执行插入操作的文件,将其数组下标存入last
for(int i=0;i<filenum;i++)
if(strcmp(file[i].filename,tmpname)==0)
{
last=i;
break;
}
if(insertpoint>=file[last].filelen)
{
cout<<"插入点溢出"<<endl;
return;
}
//brpoint记录当前文件扫描到的位置
brpoint=file[last].filestart;
for(i=0;i<insertpoint-1;i++)
brpoint=FAT[brpoint];//扫描直到找到插入位置
//寻找一个空闲块插入
for(i=0;i<DISC;i++)
if(FAT[i]==0)
{
FAT[i]=FAT[brpoint];
FAT[brpoint]=i;
break;
}
//改变空闲块个数与文件长度
file[last].filelen++;
blankspace--; cout<<endl<<"文件 "<<(filenum-1)<<endl;
cout<<"名称 和 大小 :"<<tmpname<<" "<<file[last].filelen<<endl;
}
#include"file.h"
extern void write(char *tmpname,int tmplen);
extern void cover(char *tmpname,int tmplen);
extern void insert(char *tmpname,int insertpoint);
//文件结构数组
fileinfo file[FILENUM];
int filenum;//文件数量
int FAT[DISC],blankspace;//FAT表和剩余空间
int main(int argc,char *argv[])
{
char tmpname[FILENAMELEN];
int tmplen;//要写入文件长度
int order;//命令
filenum=0;
//初始化FAT表
for(int i=0;i<DISC;i++)
FAT[i]=0;
FAT[0]=FDF;
FAT[1]=FFF;
blankspace=98;
while(1)
{
cout<<"请选择操作:"<<endl<<"1 存"<<endl<<"2 插入"<<endl;
cout<<"按其他键推出!"<<endl;
cin>>order;
switch(order)
{
case 1: cout<<"请输入文件名称:"<<endl;
cin>>tmpname;
cout<<"请输入文件的页数:"<<endl;
cin>>tmplen;
//判断是否有重名文件
for(i=0;i<filenum;i++)
if(strcmp(file[i].filename,tmpname)==0)
{ //若同意覆盖,则进入覆盖函数,否则进行下一次操作
cout<<"覆盖原来文件?(y/n)"<<endl;
char tmpch=getchar();
if(tmpch == 'y' || tmpch == 'Y')
{
cover(tmpname,tmplen);
break;
}
else break;
}
//若无重名文件则写入,写入前判断是否有足够空间
if(tmplen>blankspace)
{
cout<<"没有足够的空间!"<<endl;
break;
}
if(i==filenum) write(tmpname,tmplen);
break;
case 2: cout<<"请输入要插入块的文件名称:"<<endl;
cin>>tmpname;
int insertpoint;
cout<<"请输入要插入块的位置:"<<endl;
cin>>insertpoint;
for(i=0;i<filenum;i++)
if(strcmp(file[i].filename,tmpname)==0)
break;
if(i==filenum)
{
cout<<"没有此文件名"<<endl;
break;
}
//若无空间,则不插入
if(blankspace==0)
{
cout<<"没有足够的空间!"<<endl;
break;
}
insert(tmpname,insertpoint);
break;
default :break;
}
//询问是否继续输入命令
cout <<endl<<endl<<endl<< "继 续?(y/n)"<<endl;
fgets(tmpname, sizeof(tmpname), stdin);
if(*tmpname != 'y'&& *tmpname != 'Y')
return 0;
putchar('\n');
}
}