文件管理.docx
《文件管理.docx》由会员分享,可在线阅读,更多相关《文件管理.docx(46页珍藏版)》请在冰豆网上搜索。
文件管理
武夷学院实验报告
课程名称:
_______操作系统_______项目名称:
________进程管理_________
姓名:
_李辉文_专业:
_计科__班级:
__2_学号:
_4__同组成员__无__
一、实验预习部分:
实验目的及要求
1.帮助了解文件系统的特点。
2.通过模拟文件管理的工作过程,从而对各种文件操作命令的实质内容和执行过程有更深入的了解
实验设备(环境)及要求
一台运行Windows 操作系统并安装了VC++的计算机。
二、实验过程记录部分:
实验内容与步骤
程序功能方面要求实现一个命令行操作界面,包含如下命令:
1.改变目录。
格式:
CD<目录名>
功能:
工作目录转移到指定的目录下,只要求完成改变到当前目录的某一个子目录下的功能,不要求实现相对目录以及绝对目录。
1.创建文件。
格式:
CREATE<文件名> <文件长度>
功能:
创立一个指定名字的新文件,即在目录中增加一项,不考虑文件内容,但必须能输入文件长度。
1.删除文件。
格式:
DEL<希望删除的文件名>
功能:
删除指定的文件。
1.显示目录。
格式:
LSALL
功能:
显示全部目录以及文件,输出时要求先输出接近根的目录,再输出子目录。
1.创建目录。
格式:
MD<目录名>
功能:
在当前路径下创建指定的目录。
(6)删除目录。
格式:
RD<目录名>
功能:
删除当前目录下的指定目录,如果该目录为空,则可删除,否则应提示是否作删除,删除则将该目录下的全部文件和子目录都删除。
程序源代码如下:
#include
#include
#include
usingnamespacestd;
/*---------常变量------*/
constunsignedintBLOCK_SIZE=512;//块长
constunsignedintDATA_BLOCK_NUM=512;//数据块数量
constunsignedintDINODE_START=4*BLOCK_SIZE;//inode起始位置
constunsignedintDINODE_SIZE=512;//inode大小
constunsignedintDINODE_NUM=512;//inode数量
constunsignedintDATA_START=(2+DINODE_NUM)*BLOCK_SIZE;//数据区的开始地址
constunsignedintACCOUNT_NUM=10;//用户数量
constunsignedintDIRECTORY_NUM=12;//每个目录最多允许拥有的子目录和文件
constunsignedshortFILE_NAME_LENGTH=20;//最大文件名长度
/**************************
inode结构体
**************************/
/*inode结构体*/
structinode{
unsignedshortdi_tag;/*inode标识*/
unsignedshortdi_number;/*关联文件数,当为0时表示删除文件,如一个目录至少包含两个文件:
"."和".."*/
unsignedshortdi_mode;/*存取模式:
0为目录,1为文件*/
unsignedshortdi_userID;/*当前inode所属用户0为根目录ID,一次下去是管理员目录、用户目录*/
unsignedshortdi_access;/*访问权限0为不允许普通用户访问(公共目录),1为允许普通用户访问*/
unsignedshortdi_size;/*文件大小,目录没有大小,值为0*/
unsignedshortdi_ctime;/*创建时间*/
unsignedshortdi_mtime;/*最后一次修改时间*/
unsignedshortdi_block;/*数据块块地址编号*/
};
/*————————————————————————
超级块结构
————————————————————————*/
structsuper_block{
unsignedshorts_inodes_count;/*文件系统中inode的总数*/
unsignedshorts_free_inodes_count;/*空闲的inode总数*/
unsignedshorts_blocks_count;/*块总数*/
unsignedshorts_r_blocks_count;/*保留块总数*/
unsignedshorts_free_blocks_count;//空闲块总数
unsignedshorts_log_block_size;/*block的大小*/
//unsignedshorts_free_blocks_group[GROUPNUM];//新增一个数组来记录每个数据块组中的空闲数据块计数
//unsignedshorts_first_data_block;/*第一个数据block*/
//unsignedshorts_blocks_per_group;/*每blockgroup的block数量*/
//unsignedshorts_inodes_per_group;/*每blockgroup的inode数量*/
};
/*————————————————————————
账户信息
————————————————————————*/
structuser{
unsignedshortuser_id;//用户ID
unsignedshortuser_access;//权限1为管理员0为平民
stringusername;//用户名
stringpassword;//密码
};
/*————————————————————————
文件、目录项结构
————————————————————————*/
structdirectory{
stringname;/*目录、文件名*/
stringcontent;/*文件数据,目录则没有数据*/
unsignedshortd_ino;/*目录、文件号*/
};
/*----变量--------*/
unsignedshortdi_bitmap[DINODE_NUM];//硬盘inode节点位图1表示已使用0表示未使用
unsignedshortbk_bitmap[DATA_BLOCK_NUM];//数据块block位图
structsuper_blocksuperBlock;//超级块
structuseraccount[ACCOUNT_NUM];//共创建ACCOUNT_NUM个账户
FILE*f_stream;//文件指针
structinode*cur_inode;//inode当前目录指针
structinode*inode_temp;//inode临时指针
constchardiskName[30]="ext2forlinux.disk";//模拟硬盘的文件名
structdirectorydir_buf[DIRECTORY_NUM];//目录数组,每个目录最多允许有12个项(子目录或者文件)
stringcur_Path;//cmd的头表示所在哪个文件夹
//inti_lock=0;//inode位图锁可能会多线程
//intb_lock=0;//block位图锁
structuser*cur_user;//当前用户
structdirectorycur_dir[DIRECTORY_NUM];//当前目录
/**********************
函数声明
********************/
boolFormat(void);//此函数用于格式化
boolinstall(void);//此函数用于装载虚拟硬盘的数据
intFindFile(stringfilename);//次函数用于查找当前文件夹是否有该文件
boolaccess(structinode*pinode);//权限判断
intmain(){
voidlogin(void);//此函数用于用户登陆
voidshowMenu(void);//此函数用于显示功能菜单
boolonAction(void);//此函数用于用户选择功能并执行
charformat_bool;
/**************初始化************/
cout<<"系统已启动,是否初始化所有数据?
\tY/N"<while(true){
cin>>format_bool;
if(format_bool=='y'||format_bool=='Y'){
if(!
Format())return0;
break;
}
elseif(format_bool=='n'||format_bool=='N'){
cout<<"不初始化不能开始!
"<continue;
}
else{
cout<<"请输入Y或者N"<continue;
}
}
cout<<"初始化成功!
"<cout<<"欢迎使用本程序,学号:
20134012004姓名:
李辉文"</********转载虚拟硬盘数据***********/
if(!
install()){
cout<<"加载失败,无效的硬盘格式"<//main();
return0;
}
elsecout<<"加载disk成功!
"<cur_Path=cur_dir[1].name+"\\root";
/*******登陆**********/
login();
/**显示菜单**/
showMenu();
/**显示当前路径**/
cout<while(onAction());
return0;
}
/*此函数用于格式化*/
boolFormat(){
//创建文件
f_stream=fopen(diskName,"wb+");
if(f_stream==NULL){
cout<<"创建文件失败"<returnfalse;
}
//初始化超级块
superBlock.s_inodes_count=DINODE_NUM;/*文件系统中inode的总数*/
superBlock.s_free_inodes_count=DATA_BLOCK_NUM-2-ACCOUNT_NUM;/*空闲的inode总数初始化时,主目录和账户信息各占一块,10个用户10块*/
superBlock.s_blocks_count=DATA_BLOCK_NUM;/*块总数*/
superBlock.s_free_blocks_count=DATA_BLOCK_NUM-2-ACCOUNT_NUM;//空闲块总数主目录/10个用户/账户信息共占用12个
superBlock.s_log_block_size=BLOCK_SIZE;/*block的大小*/
//超级块放第1个物理块,第0个为引导
fseek(f_stream,BLOCK_SIZE,SEEK_SET);
fwrite(&superBlock,BLOCK_SIZE,1,f_stream);
//fprintf(f_stream,"thisissuperblock");//测试
//初始化dinode位图block位图
for(inti=0;iif(i<2+ACCOUNT_NUM)bk_bitmap[i]=1;
elsebk_bitmap[i]=0;
}
//初始化block位图
for(i=0;iif(i<2+ACCOUNT_NUM)di_bitmap[i]=1;
elsedi_bitmap[i]=0;
}
//位示图存放与第2.3块
fseek(f_stream,BLOCK_SIZE*2,SEEK_SET);
fwrite(&di_bitmap,BLOCK_SIZE,1,f_stream);
//fprintf(f_stream,"thisissuperblock");//测试
fseek(f_stream,BLOCK_SIZE*3,SEEK_SET);
fwrite(&bk_bitmap,BLOCK_SIZE,1,f_stream);
//fprintf(f_stream,"thisissuperblock");//测试
//初始化inode表
structinode*node_temp;
node_temp=newinode;
if(!
node_temp)
{
printf("node_temp内存分配失败!
");
returnfalse;
}
//主目录的inode
node_temp->di_tag=0;//i节点标志
node_temp->di_number=2+ACCOUNT_NUM;//关联12个文件夹
node_temp->di_mode=0;//0为目录
node_temp->di_userID=0;//用户id第一个用户
node_temp->di_access=0;//0为公共可以访问
node_temp->di_size=0;//目录无size
node_temp->di_ctime=0;/*创建时间*/
node_temp->di_mtime=0;/*修改时间*/
node_temp->di_block=0;
fseek(f_stream,DINODE_START,SEEK_SET);
fwrite(node_temp,sizeof(structinode),1,f_stream);
//账户信息的inode
node_temp->di_tag=1;
node_temp->di_number=0;//无文件关联,此项等于0表明是账户信息,可用作区别于文件、目录的标识
node_temp->di_mode=0;//0为目录
node_temp->di_userID=0;//用户id第一个用户
node_temp->di_access=0;//0为公共可以访问
node_temp->di_size=0;//无size
node_temp->di_ctime=0;/*创建时间*/
node_temp->di_mtime=0;/*修改时间*/
node_temp->di_block=1;/**账户信息存在数据块的第1块**/
fseek(f_stream,DINODE_START+BLOCK_SIZE,SEEK_SET);
fwrite(node_temp,sizeof(structinode),1,f_stream);
//管理员和9个普通用户的inode
for(i=1;i<=ACCOUNT_NUM;i++){
node_temp->di_tag=i+1;//inode标志
node_temp->di_number=2;//关联2个文件夹
node_temp->di_access=1;//1为用户私有
node_temp->di_mode=0;//0为目录
node_temp->di_userID=i;//用户id第一个用户
node_temp->di_size=0;//目录无size
node_temp->di_ctime=0;/*创建时间*/
node_temp->di_mtime=0;/*修改时间*/
node_temp->di_block=i+1;//所占物理块号.从管理员到user9占用的位置为2~11.
fseek(f_stream,DINODE_START+BLOCK_SIZE*(i+1),SEEK_SET);
fwrite(node_temp,sizeof(structinode),1,f_stream);
}
/*******初始化主目录**********/
dir_buf[0].name=".";
dir_buf[0].d_ino=0;
dir_buf[1].name="..";
dir_buf[1].d_ino=0;
dir_buf[2].name="admin";
dir_buf[2].d_ino=2;//管理员的inode号为2
//user1~user9的目录项
for(i=0;idir_buf[i+3].name="user"+i;
dir_buf[i+3].d_ino=i+3;
}
fseek(f_stream,DATA_START,SEEK_SET);
fwrite(dir_buf,BLOCK_SIZE,1,f_stream);
/**初始化账户信息**/
structuseraccount_temp[ACCOUNT_NUM];
//管理员账户
account_temp[0].username="admin";
account_temp[0].password="admin";
account_temp[0].user_access=1;//1为管理员
account_temp[0].user_id=2;//管理员目录的块号
//user1~user9
for(i=1;iaccount_temp[i].username="user"+i;
account_temp[i].password="user"+i;
account_temp[i].user_access=0;
account_temp[i].user_id=i+2;//user[i]的物理块号
}
fseek(f_stream,DATA_START+BLOCK_SIZE,SEEK_SET);
fwrite(account_temp,BLOCK_SIZE,1,f_stream);
/**初始化admin目录以及user1~user9**/
//清空dir_buf
for(i=0;idir_buf[i].d_ino=0;
dir_buf[i].name="\0";
}
for(i=0;idir_buf[0].d_ino=2;
dir_buf[0].name=".";
dir_buf[1].d_ino=0;
dir_buf[1].name="..";
fseek(f_stream,DATA_START+BLOCK_SIZE*(i+2),SEEK_SET);//管理员在第二块物理空间
}
returntrue;
}
/*此函数用于装载虚拟硬盘的数据*/
boolinstall(void){
/**函数声明**/
inode*getInode(unsignedint);//获取指定inode号的inode单元
boolgetDataBlock(unsignedint);//获取指定数据块号下的目录或文件
inti;
cout<<"installing..."<f_stream=fopen(diskName,"rb+");//只读方式打开硬盘模拟文件
if(f_stream==NULL)
{
cout<<"文件打开失败"<return0;
}
//读超级块
fseek(f_stream,BLOCK_SIZE,SEEK_SET);
fread(&superBlock,sizeof(structsuper_block),1,f_stream);
//////
cout<<"加载超级块:
"<inode_temp=newinode;
if(!
inode_temp)
{
cout<<"cur_inode内存分配失败!
"<return0;
}
cur_inode=newinode;
if(!
cur_inode)
{
cout<<"cur_inode内存分配失败!
"<return0;
}
//读取inode位示图
fseek(f_stream,BLOCK_SIZE*2,SEEK_SET);
fread(di_bitmap,BLOCK_SIZE,1,f_stream);
cout<<"加载inode位示图:
"<//读取block位示图
fseek(f_stream,BLOCK_SIZE*3,SEEK_SET);
fread(bk_bitmap,BLOCK_SIZE,1,f_stream);
cout<<"加载block位示图:
"<//读取账户信息的inode
inode_temp=getInode
(1);
if(inode_temp==NULL)
{
cout<<"加载账户信息失败!
"<returnfalse;
}
//changeinode();//交换指针后cur_inode指向当前目录的inode
//读取账户信息
cout<<"账户信息块号:
"<di_block<//fseek(f_stream,DATA_START+BLOCK_SIZE*inode_temp->di_block,SEEK_SET);
fread(account,BLOCK_SIZE,1,f_stream);
//cout<<"加载账户信息:
"<