1、实验目的
通过具体的文件存储空间的管理、文件的物理结构、目录结构和文件操作的实现,加深对文件系统内部功能和实现过程的理解。
2、实验内容
(1)在内存中开辟一个虚拟磁盘空间作为文件存储器,在上面实现一个简单单用户文件系统。退出时应该将该虚拟文件系统保存到磁盘上,以便下次可以再将它恢复到内存对虚拟磁盘空间中。
(2)文件存储空间对分配可以采用显式链接分配或者其他的办法。
(3)空闲空间的管理可以选择位示图或者其他的办法。如果采用位示图来管理文件存储空间,并采用显式链接分配方式,那么可以将位示图合并到FAT中。
(4)文件目录结构采用多级目录结构。为了简单起见,可以不使用索引结点,其中的每个目录项应包含文件名、物理地址、长度等信息,还可以通过目录项实现对文件对读和写的保护。
(5)要求提供以下有关的操作:
√ format:对文件存储器进行格式化,即按照文件系统对结构对虚拟磁盘空间进行布局,并在其上创建根目录以及用于管理文件存储空间等的数据结构。
√mkdir:用于创建子目录;
√rmdir:用于删除目录;
√ls:用于显示目录;
√cd:用于更改当前目录;
√create:用于创建文件;
√open:用于打开文件;
√close:用于关闭文件;
√write:用于写文件;
√read:用于读文件
√rm:用于删除文件。
核心代码
int dir()
{
int i=0,j=0;
temp=new filenode;
temp=recent;
if(temp==root)
{cout<<" <DIR> "<<"."<<endl; }
if(temp!=root)
{cout<<" <DIR> "<<".."<<endl;i++;}
if(temp->child==NULL)
{
cout<<"Total: "<<" directors " <<i<<" files "<< j <<endl;
return 1;
}
temp=temp->child;
while(temp)
{
if(temp->isdir)
{cout<<" <DIR> "<<temp->filename<<endl;i++;}
else
{cout<<" <FILE> "<<temp->filename<<endl;j++;}
temp=temp->next;
}
cout<<"Total: "<<" directors " <<i<<" files "<< j <<endl;
return 0;
}
int read()
{
char filename[FILENAME_LENGTH];
cin>>filename;
if(recent->child==NULL)
{
cout<<"文件不存在!"<<endl;
return 1;
}
if(strcmp(recent->child->filename,filename)==0)
{
cout<<recent->child->content<<endl;
return 0;
}
else
{
temp=recent->child;
while(temp->next)
{
if(strcmp(temp->next->filename,filename)==0)
{
cout<<temp->next->content<<endl;
return 0;
}
}
cout<<"文件不存在!"<<endl;
return 1;
}
}
int write()
{
char filename[FILENAME_LENGTH];
cin>>filename;
if(recent->child==NULL)
{
cout<<"文件不存在!"<<endl;
return 1;
}
if(strcmp(recent->child->filename,filename)==0)
{
cin>>recent->child->content;
cout<<"文件写入成功!"<<endl;
return 0;
}
else
{
temp=recent->child;
while(temp->next)
{
if(strcmp(temp->next->filename,filename)==0)
{
cin>>temp->next->content;
cout<<"文件写入成功!"<<endl;
return 0;
}
}
cout<<"文件不存在!"<<endl;
return 1;
}
}
int del()
{
char filename[FILENAME_LENGTH];
cin>>filename;
temp=new filenode;
if(recent->child)
{
temp=recent->child;
while(temp->next && (strcmp(temp->filename,filename)!=0 || temp->isdir!=0))
temp=temp->next;
if(strcmp(temp->filename,filename)!=0 || temp->isdir!=0)
{
cout<<"不存在该文件!"<<endl;
return 0;
}
}
else
{
cout<<"不存在该文件!"<<endl;
return 0;
}
if(temp->parent==NULL)
{
temp->prev->next=temp->next;
if(temp->next)
temp->next->prev=temp->prev;
temp->prev=temp->next=NULL;
}
else
{
if(temp->next)
temp->next->parent=temp->parent;
temp->parent->child=temp->next;
}
delete temp;
cout<<"文件已删除!"<<endl;
return 0;
}
int rm()
{
char filename[FILENAME_LENGTH];
cin>>filename;
temp=new filenode;
if(recent->child)
{
temp=recent->child;
while(temp->next && (strcmp(temp->filename,filename)!=0 || temp->isdir!=1))
temp=temp->next;
if(strcmp(temp->filename,filename)!=0 || temp->isdir!=1)
{
cout<<"不存在该目录!"<<endl;
return 0;
}
}
else
{
cout<<"不存在该目录!"<<endl;
return 0;
}
if(temp->parent==NULL)
{
temp->prev->next=temp->next;
if(temp->next)
temp->next->prev=temp->prev;
temp->prev=temp->next=NULL;
}
else
{
if(temp->next)
temp->next->parent=temp->parent;
temp->parent->child=temp->next;
}
delete temp;
cout<<"目录已删除!"<<endl;
return 0;
}
int cd()
{ char topath[PATH_LENGTH];
cin>>topath;
if(strcmp(topath,".")==0)
return 0;
if(strcmp(topath,"..")==0)
{
int i;
while(recent->prev)
recent=recent->prev; //向前回溯,找到第一次创建的目录
if(recent->parent)
{
recent=recent->parent;
}
i=strlen(path);
// printf("%d %s\n",i,path);
while(path[i]!='/' && i>0)
i--; //找到最右边的/
if(i!=0)
{ path[i]='\0';
//printf("%s",path); //path中不止有一个/
}
else
path[i+1]='\0';
}
else
{
findpath(topath);
}
return 0;
}
int findpath(char *topath)
{
unsigned int i=0;
int sign=1;
if(strcmp(topath,"/")==0) //如果命令是cd /
{
recent=root;
strcpy(path,"/");
return 0;
}
temp=recent;
strcpy(temppath,path);
if(topath[0]=='/') //cd命令以cd /开始
{
recent=root->child;
i++;
strcpy(path,"/");
// printf("\n%s",path);
}
else
{
if(recent!=NULL && recent!=root)
{
strcat(path,"/");
// printf("\n%s\n",path);
}
if(recent && recent->child)
{
if(recent->isdir)
recent=recent->child;
else
{
printf("路径错误!\n");
return 1;
}
}
}
while(i<=strlen(topath) && recent)
{
int j=0;
if(topath[i]=='/' && recent->child)
{
i++;
if(recent->isdir)
recent=recent->child;
else
{printf("路径错误\n");
return 1;
}
strcat(path,"/");
}
while(topath[i]!='/' && i<=strlen(topath))
{
recentpath[j]=topath[i];
i++;j++;
}
recentpath[j]='\0';
while((strcmp(recent->filename,recentpath)!=0 || (recent->isdir!=1)) && recent->next!=NULL)
{
recent=recent->next;
}
if(strcmp(recent->filename,recentpath)==0)
{
if(recent->isdir==0)
{strcpy(path,temppath);
recent=temp;
printf("是文件不是目录。\n");
return 1;
}
strcat(path,recent->filename);
}
if(strcmp(recent->filename,recentpath)!=0 || recent==NULL)
{
strcpy(path,temppath);
recent=temp;
printf("输入路径错误\n");
return 1;
}
}
return 0;
}
int mkdir()
{
temp=initnode(" ",1);
cin>>temp->filename;
if(recent->child==NULL)
{
temp->parent=recent;
temp->child=NULL;
recent->child=temp;
temp->prev=temp->next=NULL;
printf("目录建立成功!\n");
}
else
{
ttemp=recent->child;
if(strcmp(ttemp->filename,temp->filename)==0&&ttemp->isdir==1)
{
{
printf("目录已存在!\n");
return 1;
}
}
while(ttemp->next)
{
ttemp=ttemp->next;
if(strcmp(ttemp->filename,temp->filename)==0&&ttemp->isdir==1)
{
printf("目录已存在!\n");
return 1;
}
}
ttemp->next=temp;
temp->parent=NULL;
temp->child=NULL;
temp->prev=ttemp;
temp->next=NULL;
printf("目录建立成功!\n");
}
return 0;
}
int create()
{
temp=initnode(" ",0);
cin>>temp->filename;
if(recent->child==NULL)
{
temp->parent=recent;
temp->child=NULL;
recent->child=temp;
temp->prev=temp->next=NULL;
cout<<"文件创建成功!"<<endl;
}
else
{
ttemp=recent->child;
if(strcmp(ttemp->filename,temp->filename)==0&&ttemp->isdir==0)
{
printf("文件已存在!\n");
return 1;
}
while(ttemp->next)
{
ttemp=ttemp->next;
if(strcmp(ttemp->filename,temp->filename)==0&&ttemp->isdir==0)
{
printf("文件已存在!\n");
return 1;
}
}
ttemp->next=temp;
temp->parent=NULL;
temp->child=NULL;
temp->prev=ttemp;
temp->next=NULL;
cout<<"文件建立成功!"<<endl;
}
return 0;
}