4文件系统要点.docx
《4文件系统要点.docx》由会员分享,可在线阅读,更多相关《4文件系统要点.docx(29页珍藏版)》请在冰点文库上搜索。
4文件系统要点
实验四文件系统
实验名称:
文件系统
实验目的:
模拟文件系统实现的基本功能,了解文件系统的基本结构和文件的各种管理方法,加深理解文件系统的内部功能及内部实现。
实验类型:
验证
实验学时:
4
实验环境:
1.Windows操作系统下,MicrosoftVisualC++编程环境(6.0)。
2.Windows操作系统下,MicrosoftVisualStudioC#编程环境(2010)。
实验步骤:
第一模块:
在MicrosoftVisualC++编程环境下,模拟DOS文件系统
通过编写和调试一个简单的文件系统,模拟文件管理的工作过程,从而对各种文件操作命令的实质内容和执行过程有比较深入的了解。
1、打开MicrosoftVisualC++6.0;选择“文件”->“新建”。
2、选择Win32ConsoleApplication;建立一个“Hello,World!
”程序。
3、在SourceFiles文件夹的filename.cpp中输入源代码,调试运行程序。
4、源代码
#include"stdafx.h"
#include"stdlib.h"
#include"stdio.h"
#include"iostream.h"
#include"string.h"
#include"ctype.h"
#include"conio.h"
#defineFILENAME_LEN21
#defineINPUT_LEN81
#defineCOMMAND_LEN11
//结点结构
structFileNode
{
charfilename[FILENAME_LEN];//文件名/目录名
intisdir;//目录文件识别标志
inti_nlink;//文件的链接数
intadr;//文件的地址
structFileNode*parent,*child;//指向父亲的指针和指向左孩子的指针
structFileNode*sibling_prev,*sibling_next;//指向前一个兄弟的指针和指向;后一个兄弟的指针.
};
voidInit();//初始化文件树
intParseCommand();//接受输入的命令并把其分解成操作名和路径文件名
voidExecuteCommand();//执行命令
intcdComd();//处理cd命令
inteditComd();//处理edit命令
intdelComd();//处理del命令
intrdComd();//处理rd命令
intdirComd();//处理dir命令
intmdComd();//处理md命令
intFindPath(char*ph);//寻找参数ph所指向的路径
intFindFilename(charPara2[]);//从参数Para2中找到要建立或删除的文件、目录名,并把指针指向其父亲结点
structFileNode*CreateFileNode(charfilename[],intisdir,inti_nlink);//创建结点
intGetInput(char*buffer,unsignedintbuffer_len);//获取输入
intCheckCommand();//命令检查
intGetDir(intbegin,char*path,char*curDir);//获取路径
voidTrim(char*str);
structFileNode*cp,*tp,*root,*upper;
charpath[INPUT_LEN-COMMAND_LEN];//记录当前走过的路径
charcurpath[INPUT_LEN-COMMAND_LEN],Para1[COMMAND_LEN],
Para2[INPUT_LEN-COMMAND_LEN],tmppath[INPUT_LEN-COMMAND_LEN];
charfilename[FILENAME_LEN],dirname[FILENAME_LEN],tmp;
inti,j;
//主函数
intmain()
{
Init();//初始化文件树
while
(1)
{
if(ParseCommand())//分解命令
ExecuteCommand();//执行命令
}
return0;
}
//初始化文件树
voidInit()
{
structFileNode*bin,*usr,*unix,*etc;
strcpy(path,"/");//根目录为当前目录
////////////////////////////////////////////////////////////////////////
/////////////////////创建初始目录结点///////////////////////////////////
bin=CreateFileNode("bin",1,0);
usr=CreateFileNode("usr",1,0);
unix=CreateFileNode("unix",0,0);
etc=CreateFileNode("etc",1,0);
root=cp=tp=CreateFileNode("/",1,0);
////////////////////////////////////////////////////////////////////////
/////////////////////创建初始目录结点结束///////////////////////////////
////////////////////////////////////////////////////////////////////////
/////////////////////初始目录赋值///////////////////////////////////////
root->parent=NULL;
root->child=bin;
root->sibling_prev=root->sibling_next=NULL;
bin->parent=root;
bin->child=NULL;
bin->sibling_prev=NULL;
bin->sibling_next=usr;
usr->parent=NULL;
usr->child=NULL;
usr->sibling_prev=bin;
usr->sibling_next=unix;
unix->parent=NULL;
unix->child=NULL;
unix->sibling_prev=usr;
unix->sibling_next=etc;
etc->parent=NULL;
etc->child=NULL;
etc->sibling_prev=unix;
etc->sibling_next=NULL;
////////////////////////////////////////////////////////////////////////
/////////////////////初始目录结点赋值结束///////////////////////////////
printf("***********************************************************************\n");
printf("***********************************************************************\n");
printf("***********************欢迎来到模拟文件管理系统************************\n");
printf("*******************************软件工程********************************\n");
printf("***********************************************************************\n");
printf("你可以输入如下命令进行操作:
\n");
printf("cd:
类似dos的cd命令\n");
printf("edit:
创建文件\n");
printf("del:
删除文件\n");
printf("rd:
删除目录\n");
printf("dir:
显示目录\n");
printf("md:
创建目录\n");
}
//执行命令子函数
voidExecuteCommand()
{
intsign;
//根据参数Para1调用相应的功能处理模块
if(strcmp(Para1,"cd")==0)
sign=cdComd();//cd命令
elseif(strcmp(Para1,"edit")==0)
sign=editComd();//edit命令
elseif(strcmp(Para1,"del")==0)
sign=delComd();//del命令
elseif(strcmp(Para1,"dir")==0)
sign=dirComd();//dir命令
elseif(strcmp(Para1,"md")==0)
sign=mdComd();//md命令
elseif(strcmp(Para1,"rd")==0)
sign=rdComd();//rd命令
elseif(strcmp(Para1,"exit")==0)
exit(0);//exit命令
else
printf("命令错误,请重试\n");//命令输入不正确,报错
}
//创建结点
structFileNode*CreateFileNode(charfilename[],intisdir,inti_nlink)
{
//申请结点空间
structFileNode*node=(structFileNode*)malloc(sizeof(structFileNode));
//相应内容赋初值
strcpy(node->filename,filename);
node->isdir=isdir;
node->i_nlink=i_nlink;
node->parent=NULL;
node->child=NULL;
node->sibling_prev=NULL;
node->sibling_next=NULL;
returnnode;
}
//获取文件或目录名,并把指针指向其父亲结点
intFindFilename(charPara2[])
{
i=strlen(Para2)-1;
j=0;
while(Para2[i]!
='/'&&i>=0)
{
filename[j]=Para2[i];
i--;
j++;
}
filename[j]='\0';//获得逆序的文件或目录名,存入filename中
if(i<0)Para2[i+1]='\0';
elsePara2[i]='\0';
//j--;//filename逆转,获得正确的文件或目录名,如果不需要逆转就去掉此语句
for(i=0;i<(signed)strlen(filename)/2;i++)
{
j--;
tmp=filename[i];
filename[i]=filename[j];
filename[j]=tmp;
}
//查找路径
if(strlen(Para2)>0)
{
intsign=FindPath(Para2);
if(sign==0)return0;
}
return1;
}
//缓冲区安全输入子函数
//如果输入超过buffer_len,则截取前buffer_len-1长度的输入,
//buffer_len处字符用'/0'代替
intGetInput(char*buffer,unsignedintbuffer_len)
{
intcount=0;
while(count<(signed)buffer_len)
{
if((buffer[count]=getchar())==10)
{
buffer[count]='\0';
returncount;
}
count++;
}
while(getchar()!
=10);
buffer[buffer_len-1]='\0';
return-1;
}
//分解命令子函数
intParseCommand()
{
charInputs[INPUT_LEN];
inti=0,j=0,k=0,ch;
printf("%s>",path);
//获取输入
if(GetInput(Inputs,INPUT_LEN)==-1)
{
printf("输入行太长。
\n");
return0;
}
Para1[0]=Para2[0]='\0';
//获取参数Para1,即操作名
while(Inputs[i]!
=''&&Inputs[i]!
='\0'&&i{
Para1[i]=Inputs[i];
i++;
}//while
Para1[i]='\0';
//输入命令太长
if(i==(COMMAND_LEN-1))return1;
//获取参数2,即路径文件名
if(Inputs[i]!
='\0')
{
while(Inputs[i]==''&&ij=0;
while(Inputs[i]!
='\0'&&i{
Para2[j]=Inputs[i];
i++;j++;
}
Para2[j]='\0';
}
Trim(Para1);
Trim(Para2);
//将操作名全部转换成小写字母
for(k=0;k<(signed)strlen(Para1);k++)
{
ch=tolower((int)Para1[k]);
Para1[k]=ch;
}
return1;
}
//cd功能处理子函数
intcdComd()
{
if(!
CheckCommand())//命令检查
return0;
if(strcmp(Para2,"..")==0)
{//对cd..命令的处理
inti;
while(cp->sibling_prev)
cp=cp->sibling_prev;//找到这一层最左边的结点
if(cp->parent)
{
cp=cp->parent;//找到父亲结点
}
else
{
return0;
}
//对当前路径进行相应处理
i=strlen(path);
while(path[i]!
='/'&&i>0)i--;
if(i!
=0)
path[i]='\0';
else
path[i+1]='\0';
}
else
{
FindPath(Para2);//查找路径
}
return1;
}
//命令格式处理子函数
voidTrim(char*str)
{
intbegin,end;
char*tmp;
begin=0;
end=strlen(str);
//找到字符串第一个非空格的位置
while(str[begin]==''&&str[begin]!
='\0')begin++;
//去除字符串尾部空格
while(str[--end]=='');
str[end+1]='\0';
//除去空格
if(begin{
tmp=(char*)malloc((sizeof(char))*(end-begin+2));
strcpy(tmp,&str[begin]);
strcpy(str,tmp);
free(tmp);
}
}
//获取当前目录名子函数
intGetDir(intbegin,char*path,char*curDir)
{
inti=0;
intlen=strlen(path);
while(!
((path[begin]=='\\')||(path[begin]=='/'))&&begin{
curDir[i++]=path[begin++];
}
curDir[i]='\0';
Trim(curDir);
returnbegin+1;
}
//查找路径子函数
intFindPath(char*ph)
{
structFileNode*temp;//*tp,
charoldpath[INPUT_LEN-COMMAND_LEN];
inti=0;
intsign=1;
if(strcmp(ph,"/")==0)
{//ph是根目录
cp=root;
strcpy(path,"/");
return1;
}
temp=cp;
strcpy(oldpath,path);//保存原路径和指针
if(ph[0]=='/')
{//指针指向根目录的左孩子
cp=root->child;
i++;//滤过'/'
strcpy(path,"/");
}
else
{
if(cp!
=NULL&&cp!
=root)
strcat(path,"/");
if(cp&&cp->child)
{
if(cp->isdir)
cp=cp->child;//指针指向当前目录的左孩子
else
{
printf("路径错误!
\n");
return0;
}
}
}
while(i<=(signed)strlen(ph)&&cp)//继续查找指定路径,如遇到文件则报错
{
intj=0;
if(ph[i]=='/'&&cp->child)
{
i++;//略过'/'
if(cp->isdir)
cp=cp->child;//继续查找下级目录
else
{
printf("路径错误!
\n");
return0;
}
strcat(path,"/");
}
//curpath记录当前要找的路径名
while(ph[i]!
='/'&&i<=(signed)strlen(ph))
{
curpath[j]=ph[i];
i++;j++;
}
curpath[j]='\0';
while((strcmp(cp->filename,curpath)!
=0||(cp->isdir!
=1))&&cp->sibling_next!
=NULL)
{
cp=cp->sibling_next;
}
if(strcmp(cp->filename,curpath)==0)
{
if(cp->isdir==0)
{
strcpy(path,oldpath);
cp=temp;
printf("是文件不是目录.\n");
return0;
}
strcat(path,cp->filename);
}
if(strcmp(cp->filename,curpath)!
=0||cp==NULL)
{
strcpy(path,oldpath);
cp=temp;
printf("输入路径错误\n");
return0;
}
}
return1;
}
//创建文件子函数
inteditComd()
{
structFileNode*temp=CreateFileNode("",0,0);
intsign;
structFileNode*tp;
//路径不能为空
if(strlen(Para2)==0)
{
printf("\n命令格式有错误.\n");
return0;
}
//长度检查
if(strlen(Para2)>50)
{
printf("\n文件名过长\n");
return0;
}
//格式检查
if(!
(isalpha(Para2[0])||Para2[0]=='_'||Para2[0]=='\0'||Para2[0]=='/'))
{
printf("文件名格式有错!
\n");/*文件首字母可以为'字母'或'数字'或'_'或'/'或'回车'*/
return0;
}
//获取文件名
sign=FindFilename(Para2);
if(sign==0)
return0;
if(cp->isdir!
=1)//如当前指针指向的是文件,则报错
{
printf("youcannoteditafileinunderafile!
\n");
return0;
}
//创建文件结点,并插入到指定目录下
tp=CreateFileNode("",1,0);
strcpy(tp->filename,filename);
tp->isdir=0;
tp->i_nlink=0;
if(cp->child==NULL)
{tp->parent=cp;
tp->child=NULL;
cp->child=tp;
tp->sibling_prev=NULL;
tp->sibling_n