实验名称:文件系统的构建
实验目的:掌握磁盘的工作原理和操作系统进行文件管理的原理
实验原理:硬盘的MBR:MBR(Main Boot Record),按其字面上的理解即为主引导记录区,位于整个硬盘的0磁道0柱面1扇区。在总共512字节的主引导扇区中,MBR只占用了其中的446个字节(偏移0000--偏移01BD),另外的64个字节(偏移01BE--偏移01FD)交给了DPT(Disk Partition Table硬盘分区表),最后两个字节"55,AA"(偏移01FE- 偏移01FF)是分区的结束标志。这个整体构成了硬盘的主引导扇区。
硬盘依据分区表中的信息把硬盘划分为最多四个分区(对于扩展分区,可进一步划分为多个逻辑分区)。U盘采用类似的方法划分分区。每个分区或软盘上可建立独立的文件系统。下图是FAT文件系统空间分布结构。
实验内容:在掌握磁盘的工作原理和操作系统进行文件管理原理的基础上,自行设计实现在磁盘上建立文件系统的软件,该软件应该具有与Format类似的功能,至少支持一种文件系统格式,如FAT、NTFS或EXT2,至少能够对一种媒体进行格式化,如软盘,U盘或硬盘(不得在实验室的机器上进行硬盘格式化的实验)等。不能直接调用操作系统提供的格式化工具或类似SHFormatDrive()的高层系统函数实现该软件。在Windows环境可使用biosdisk()函数完成底层盘操作,在Linux环境上可参考format的源代码。比较自己设计实现的软件.与FORMAT,分析存在什么异同。
背景知识介绍
一个分区或磁盘能作为文件系统使用前,需要初始化,并将记录数据结构写到磁盘上。这个过程就叫建立文件系统。大部分linux文件系统种类具有类似的通用结构。其中心概念是超级块superblock, i节点inode, 数据块data block,目录块directory block, 和间接块indirection block。超级块包括文件系统的总体信息。 i节点包括除了名字外的一个文件的所有信息,名字与i节点数目一起存在目录中,目录条目包括文件名和文件的i节点数目。 i节点包括几个数据块的数目,用于存储文件的数据。 i节点中只有少量数据块数的空间,如果需要更多,会动态分配指向数据块的指针空间。这些动态分配的块是间接块;为了找到数据块,这名字指出它必须先找到间接块的号码。
Linux文件系统通常允许在文件中产生孔(hole), 意思是文件系统假装文件中有一个特殊的位置只有0字节,但没有为这文件的这个位置保留实际的磁盘空间。这对小的二进制文件经常发生,Linux共享库、一些数据库和其他一些特殊情况。
设计方案
1、用一个文件(3)模拟一个物理硬盘, 通过对该文件格式化操作,模拟linux文件系统中的文件操作。
2、将文件划分为四个分区
预计的实验结果
文件会被格式化,原先文件里的内容都会删除,创建新的文件系统。
关键代码的分析
1、i节点结构
struct inode{
struct inode * i_forw;
struct inode *i_back;
char i_flag;
unsigned int i_ino;//磁盘i节点标号
unsigned int i_count;//引用计数
unsigned short di_number;//关联文件数
unsigned short di_mode;//存取权限
unsigned short di_uid;//磁盘i节点用户id
unsigned short di_gid;//磁盘i节点住id
unsigned int di_size;//大小
unsigned int di_addr[NADDR];//物理块号
};
2、目录项结构
struct direct{
char d_name[DIRSIZ];//目录名
unsigned int d_ino;//目录号
};
3、超级块
struct filsys{
unsigned short s_isize;//i节点块块数
unsigned long s_fsize;//数据块块数
unsigned int s_nfree;//空闲块块数
unsigned short s_pfree;//空闲块指针
unsigned int s_free[NICFREE];//空闲块堆栈
unsigned int s_ninode;//空闲i节点数
unsigned short s_pinode;//空闲i节点指针
unsigned int s_inode[NICINOD];//空闲i节点数组
unsigned int s_rinode;//超级块修改标志
char s_fmod;
};
4、函数说明
ifree:释放i节点区函数
bfree:磁盘块释放函数
iget:i节点内容获取函数
iput:i节点内容释放函数
format:格式化函数
调试记录
实际的实验结果
fzu@fzu-desktop:~/OS$ gcc -w -o format format.c
fzu@fzu-desktop:~/OS$ ./format
请输入文件的位置
/home/fzu/OS/3
format succuss
fzu@fzu-desktop:~/OS$
fzu@fzu-desktop:~/OS$ vim 3
在文件3中输入一些内容,运行格式化程序后,文件不再是原来的内容和格式,想要双击打开,但是显示无法打开次文件。
实验结果分析
文件确实被格式化了,但是此时这个文件是二进制文件系统,无法用gedit或其他程序打开,用vim打开后显示上图内容。
试验四 文件系统
一、 实验目的
1、 用高级语言编写和调试一个简单的文件系统,模拟文件管理的工作过程。从而对各种文件操作命令的实质内容和执行过程有比较深入的了解。
2、 要求设计一个n个用户的文件系统,每次用户可以保存M个文件。用户在一次运行中只能打开一个文件,对文件必须设置保护措施,且至少有create、delete、open、close、read、write等命令。
二、 实验题目:
采用二级目录结构实现磁盘文件操作。
要求:
1.普通文件的目录项包括文件名,文件类型,文件长度,指向文件内容的指针内容。
2.目录文件的目录项包括目录名,指向下一级目录块的指针内容。假定每个目录文件最多只能占用一个块;
3.程序功能方面的要求: 需要实现一个命令行操作界面,包含如下命令:
4.程序实现方面的要求:
(1)、对于重名(创建时),文件不存在(删除时),目录不存在(改变目录时)等错误操作情况,程序应该做出相应处理并给出错误信息,但是程序不得因此而退出。
(2)、界面友好,程序强壮。
(3)、设置界面的提示符,提示的命令以及调试的方法应和前面的要求一致。不要自己设计命令或者附加不要求的功能。
三.实验源程序文件名: Filesystem_s.cpp
执行文件名: Project1.exe
四.实验分析
1)总论:
该系统是一个多用户、多任务的实时操作系统。对用户和用户的文件数目并没有上限。也就是说该系统允许任何用户申请空间,而且在其目录下的文件数目并不做任何的限制。
该系统的操作命令如下:
①、bye-用户注销命令。当使用该命令时,用户退出系统。命令格式:
run\bye↙系统注销该用户并回到登陆界面。
②、close-删除用户注册信息命令。执行该命令后,用户在系统中的所有信息,包括该用户目录下的所有文件都被删除。命令格式:run\close↙.完成后返回登陆界面。
③、create-在当前目录下创建一个文件,且该文件不能跟系统中的文件重名。该文件的管理信息登录到用户文件信息管理模块中。命令格式:run\create>file1↙。其中file1为要创建的文件名称。执行完该命令后回到执行命令行。
④、delete-删除当前用户目录下的一个文件。命令格式:run\delete>file1↙。返回命令行。
⑤、list-显示当前注册目录下的所有文件信息,包括文件名、文件长度、文件操作权限。命令格式:run\list↙。
⑥、chmod-改变某个文件的执行权限,但前提是该文件是该用户目录下的文件。命令格式:run\chmod>file1↙。
⑦、open-在window界面下打开某个文件。命令格:run\open>file1↙。执行该命令后,文件file1将用在windows界面下的文件形式打开。用户可以在这个方式中对文件进行修改,并将修改后的内容保存。
⑧、read-读文件信息。将文件信息读入并显示在终端。命令格式:run\read>file1↙。
⑨、write-向某个文件写入新的信息。用户可以选择用覆盖原来内容的方式和在文件的末尾插入新信息的方式写入信息。
2)_系统采用二级文件目录。设置主目录(MFD)和用户文件目录(UFD),分别以文件的方式保存在磁盘中。在主目录中又注册用户的用户名和另一标志该用户目录下是否有文件的指针标记。用户文件目录用用户名作为文件名保存在磁盘,以便检索时方便对应。在用户文件目录中保存着该目录下所有的文件的文件名称、保护码、文件长度。
3) 该系统大量使用高级语言中的文件操作函数,所以能实际看到文件的创建写入、读出、删除等效果。
4) 实验流程图
5)源程序:
#include<iostream.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "conio.h"
#include<dos.h>
#define NULL 0
#define keynum 10
#define getspace(type) (type*)malloc(sizeof(type))
char cmd[64]; //存放用户输入命令
char buffer[36];//
char user[32];//存放当前登陆的用户名
typedef char ALFA[12];
ALFA KWORD[keynum];
struct UFD{//用户文件管理模块
char filename[32]; //文件名
int safecode; //文件保护码
long length; //文件长度
}*curfile = NULL;
struct MFD{//用户登陆信息管理模块
char username[32]; //用户名
bool filepoint; //用户目录下的文件指针,false表示目录为空
}*curuser = NULL,*elseuser=NULL;
typedef UFD UFD;
typedef MFD MFD;
void main();
void KeyWord()//初始化命令关键字
{
strcpy(KWORD[ 1],"bye"); strcpy(KWORD[ 2],"chmod");
strcpy(KWORD[ 3],"close"); strcpy(KWORD[ 4],"create");
strcpy(KWORD[ 5],"delete"); strcpy(KWORD[ 6],"list");
strcpy(KWORD[ 7],"open"); strcpy(KWORD[ 8],"read");
strcpy(KWORD[ 9],"write");
}
int LoginDisplay() //登陆选项操作函数
{
int SELETE_1 = 0;
do
{
cout<<" *****请选择操作*****\n1、用户登陆 2、用户注册 0、退出"<<endl;
cin>>SELETE_1;
}while(SELETE_1<0 || SELETE_1>2);
system("cls");
return SELETE_1;
}
bool Login(int SELETE)//用户登陆,注册函数
{
FILE *fp,*fp1,*fp2;
char name[12];
switch(SELETE)
{
case 1://用户登陆
if((fp = fopen("LOGIN.exe","rb")) == NULL)//打开用户注册目录管理文件
{
cout<<"\n错误:不能打开登陆文件。"<<endl;
getch();system("cls");
return false;
}
curuser = getspace(MFD);
cout<<"\n*****登陆*****\n用户名:";
cin>>name; //输入用户登陆名
while(!feof(fp)) //检查该用户是否合法
{
fread(curuser,sizeof(MFD),1,fp);
if(strcmp(curuser->username,name)==0)
break;
}
if(feof(fp)) //如果没有找到跟当前登陆用户名相同的管理信息,提示出错
{
cout<<"\n错误:该用户不存在。"<<endl;
fclose(fp);
return false;
}
else
{
fclose(fp);
return true;
}
break;
case 2: //新用户注册
if((fp=fopen("LOGIN.exe","ab"))==NULL)//如果登陆信息管理文件不存在
fp=fopen("LOGIN.exe","wb+"); //创建该信息管理文件
char name[12];
curuser = getspace(MFD);
while(1)
{
cout<<"\n *****新用户注册*****"<<endl;
cout<<"用户名:";
cin>>name; //输入用户注册名
fp1 = fopen("LOGIN.exe","rb");
while(!feof(fp1))//查看该用户名是否被别的用户占用
{
fread(curuser,sizeof(MFD),1,fp1);
if(strcmp(curuser->username,name) == 0)//该名称已经被使用
{
cout<<"\n该用户已经存在,请重新输入!"<<endl;
getch();
break;
}
}
if(feof(fp1))//该名称没有被别的用户占用
{
strcpy(curuser->username,name);
curuser->filepoint = NULL;
fwrite(curuser,sizeof(MFD),1,fp);
strcpy(user,curuser->username);//生成用户文件管理模块
strcat(user,".exe"); //用于管理用户目录下的各个文件
fp2=fopen(user,"wb+");
fclose(fp2);
cout<<"\n注册成功!"<<endl; //提示注册成功
fclose(fp1);
fclose(fp);
break;
}
}
fp = fopen("LOGIN.exe","rb"); //显示当前注册用户的名称
while(1)
{
fread(curuser,sizeof(MFD),1,fp);
if(feof(fp))
break;
cout<<curuser->username<<endl;
getch();
}
fclose(fp);
return true;
break;
default:
return false;
break;
}
}
void DisplayUFD()//打印用户信息,包括用户的各个文件
//名称、长度和操作权限的设置信息
{
if(curuser->filepoint == false)//当前用户目录下没有任何文件存在
cout<<"\n用户 "<<curuser->username<<" 文件夹是空的"<<endl;
else
{//存在文件,将所有文件信息打印在终端
FILE *fp;
char filename[12];
strcpy(filename,curuser->username);
strcat(filename,".exe");
if((fp=fopen(filename,"rb"))==NULL)//打开用户文件信息管理模块
{
cout<<"\n无法打开用户:"<<curuser->username<<" 的文件!"<<endl;
getch();
return;
}
else
{//读入并将用户全部文件信息打印在终端
cout<<"用户:"<<curuser->username<<"目录下的文件:"<<endl;
UFD *ufd;
int i=0;
ufd = getspace(UFD); //申请存放用户文件模块的空间
while(1)
{
fread(ufd,sizeof(UFD),1,fp);
if(feof(fp))//全部输出完毕,结束
break;
else//打印信息
cout<<ufd->filename<<"\t"<<ufd->length<<"\t"<<ufd->safecode<<endl;
}
}
fclose(fp);
}
}
void ByeFile(bool BOOL)//注销函数,调用次函数用户可以退出系统
{
FILE *infile,*outfile;
char out[50];
strcpy(out,"outfilelocate.exe");
if((infile=fopen("LOGIN.exe","rb"))==NULL)
{
cout<<"\n保存错误。"; // fclose(infile);
return;
}
else
{
if((outfile=fopen(out,"wb+"))==NULL)//申请一个缓冲区管理模块
//存放用户更新后的全部信息
{
cout<<"\n保存错误。";// fclose(outfile);
fclose(infile);return;
}
else
{
MFD *mfd = getspace(MFD);
while(1)
{//将旧文件管理信息读出,并保存到新的文件信息管理模块中
fread(mfd,sizeof(MFD),1,infile);
if(feof(infile))
break;
if((strcmp(mfd->username,curuser->username))==0)
{
if(BOOL)//更新当前用户信息的操作
fwrite(curuser,sizeof(MFD),1,outfile);
else continue;//如果用户想把自己的注册目录从系统中彻底删除
//则执行该操作
}
else
fwrite(mfd,sizeof(MFD),1,outfile);//写入新的模块
}
fclose(infile);fclose(outfile);
remove("LOGIN.exe");//将旧的该用户的文件管理模块删除
rename(out,"LOGIN.exe");//将新的用户的文件管理模块重命名为用户目录下的管理模块
}
}
system("cls");
main();
}
bool ClearUserFile()//用户要将自己的注册目录从系统彻底删除
//首先将该用户目录下的全部文件删除
{
FILE *fp;
char file[50];
strcpy(file,curuser->username);
strcat(file,".exe");
if((fp=fopen(file,"rb"))==NULL) //打开用户文件信息管理模块
{
// fclose(fp);
cout<<"\n操作失败。";return true;
}
else
{//将该用户目录下的文件逐个从磁盘删除
UFD *ufd = getspace(UFD);
while(1)
{
fread(ufd,sizeof(UFD),1,fp);
if(feof(fp))
break;
else
remove(ufd->filename);//删除文件
}
fclose(fp);
return true;
}
}
void ClearUserMes()//删除用户全部信息
{
char name[50];
strcpy(name,curuser->username);
strcat(name,".exe");
remove(name); //从磁盘中删除用户文件信息管理模块
ByeFile(false);//更新系统的用户登陆信息管理模块
}
void DeleteUser()//删除用户注册目录的操作
{
char ch;
cout<<"\n该操作将会是你在系统所有信息删除,下次登陆时你必须重新申请用户名!"<<endl;
cout<<"\n你确定要删除你在系统中的注册信息吗?Y/N"<<endl;
cin>>ch;
switch(ch)//提示用户确认删除
{
case 'Y':
case 'y':
if(ClearUserFile())//如果用户的全部文件已经删除了
//则可以将该用户的文件信息管理模块也从磁盘中删除
//以免在没完全删除文件却删了该文件信息管理模块
//使得这些文件无法再进行管理造成磁盘空间的浪费
ClearUserMes();//删除文件信息管理模块
break;
default:
cout<<"\n你取消了此操作!";
break;
}
}
void CreatFile()//在当前用户目录下创建文件
{
FILE *fp;
curuser->filepoint=true;
if((fp=fopen(buffer,"r"))==NULL)//如果没有跟用户输入文件名相同的文件
{
if((fp=fopen(buffer,"w"))==NULL)
{
cout<<"\n创建文件失败!";
// fclose(fp);
return;
}
fclose(fp);
}
else
{//用户要创建的文件已经存在
cout<<"\n该文件已经存在,创建另一个文件?Y/N";
char ch;
cin>>ch;
switch(ch)
{
case 'Y':
case 'y':
cout<<"\n输入新文件名:";
cin>>buffer;
strcat(buffer,".txt");
fclose(fp);
if((fp=fopen(buffer,"w"))==NULL)
{
cout<<"\n创建文件失败!";
// fclose(fp);
return;
}
fclose(fp);
break;
default:
fclose(fp);
return;
}
}
strcpy(user,curuser->username);
strcat(user,".exe");
curfile = getspace(UFD);
strcpy(curfile->filename,buffer);//文件名
curfile->length=0; //该文件长度为零
curfile->safecode=30; //设置该文件的默认权限
//11 00,文件主有读和写权,其他用户没有读写权
if((fp=fopen(user,"ab"))==NULL)
{
cout<<"\n错误:你可能不是合法用户。"<<endl;
getch();
}
else
{
fwrite(curfile,sizeof(UFD),1,fp);//将该文件信息写入用户文件信息管理模块中
cout<<"\n文件 "<<curfile->filename<<" 创建成功!";
}
fclose(fp);
}
void DeleteFile()//删除当前目录下一个文件的操作
{
char ch;
FILE *infile,*outfile;
cout<<"\n确定要删除文件:"<<buffer<<" Y/N"<<endl;
cin>>ch;//提示用户确认删除
switch(ch)
{
case 'Y':
case 'y'://更新用户文件信息管理模块,这里同样使用缓冲区模块来更新
//方法与上面将到的类似
char out[50],in[50];
strcpy(out,"outfilelocate.exe");
strcpy(in,curuser->username);
strcat(in,".exe");
if((infile=fopen(in,"rb"))==NULL)//打开该用户的文件信息管理模块
{
cout<<"\n保存错误。";
//fclose(infile);
return;
}
else
{
if((outfile=fopen(out,"wb+"))==NULL)
{
cout<<"\n保存错误。";// fclose(outfile);
fclose(infile);return;
}
else
{
UFD *ufd = getspace(UFD);
while(1)
{
fread(ufd,sizeof(UFD),1,infile);//从旧模块读出信息
if(feof(infile))
break;
if((strcmp(ufd->filename,buffer))==0)//要进行更新的信息
continue;
else
fwrite(ufd,sizeof(UFD),1,outfile);//写入新模块
}
fclose(infile);fclose(outfile);
remove(in);//在磁盘移除就模块
rename(out,in); //新模块命名为当前用户文件信息管理模块
}
}
remove(buffer);//从磁盘中删除该文件
break;
default:
break;
}
}
void ListAllFile()//显示当前用户目录下的文件信息
{
DisplayUFD();
}
void OpenFile()//在window模式下打开该文件
{
system(buffer);//buffer为文件名,如:file1.txt
}
bool QueryModElse(bool BOOL,bool &flag)//查询其它用户目录下文件的文件
//当该文件的权限允许当前用户对其执行有关操作时,返回ture
{
FILE *fp;
char user[50];
UFD *ufd = getspace(UFD);//elseuser表示除当前用户外的所有用户注册目录
strcpy(user,elseuser->username);
strcat(user,".exe");
if((fp=fopen(user,"rb"))==NULL){//打开一个其它的用户文件信息管理模块
// fclose(fp);
cout<<"\n操作出现错误,对此我们表示歉意!";return false;
}
else{
while(1){
fread(ufd,sizeof(UFD),1,fp);
if(feof(fp)){
fclose(fp);return false;
}
if(strcmp(ufd->filename,buffer)==0){
if(BOOL)//该用户请求写该文件
{
if(ufd->safecode== 31 || ufd->safecode== 33)
//1101、1111最后一位为1,有写权
return true;
else{
cout<<"\n你无权对文件 "<<buffer<<" 执行此操作!";
flag=true;return false;}
//flag设置为true,告诉上一层,无须再查找
//该文件已经找到,但用户无权执行相关操作
}
else //该用户请求读权
{
if(ufd->safecode == 32 || ufd->safecode == 33)
//1110、1111倒数第二位为1,有读权
return true;
else{
cout<<"\n你无权对文件 "<<buffer<<" 执行此操作!";
flag=true;return false;}
}
}
}
}
}
bool QueryMod(bool BOOL)//查询权限
{//首先在用户目录下查找,如果找不到用户当前要进行操作的文件名
//则在其它注册用户目录下查找
FILE *fp,*fp1;
bool flag=false;
char user[50];
UFD *ufd = getspace(UFD);
strcpy(user,curuser->username);
strcat(user,".exe");
if((fp=fopen(user,"rb"))==NULL){//打开用户文件信息管理模块
// fclose(fp);
cout<<"\n操作出现错误,对此我们表示歉意!";return false;
}
else{//查找匹配的文件名,用户目录下的文件允许用户进行读写操作
while(1){
fread(ufd,sizeof(UFD),1,fp);
if(feof(fp)){//在当前用户文件管理模块中找不到匹配文件
//则继续在其它用户注册目录下查找
fclose(fp);
fp1=fopen("LOGIN.exe","rb");
elseuser = getspace(MFD);
bool BOOL_1=false;
while(1){
fread(elseuser,sizeof(MFD),1,fp1);//读其它用户信息
if(feof(fp1) && !BOOL_1)//全部用户都查找完
//但仍然没找到匹配的文件
return false;
if(elseuser != curuser){
if((BOOL_1=QueryModElse(BOOL,flag)))//查找
return true;
if(flag)
return false;
}
}
}
if(strcmp(ufd->filename,buffer)==0){//在当前用户注册目录下
//找到该文件,返回真值
fclose(fp);return true;
}
}
}
}
bool WriteRight(int len,bool BOOL)//查看是否已经正确地写入到该文件信息中
//是则返回真值
{
char user[50],outfile[50];
FILE *fp,*fp1;
strcpy(user,elseuser->username);
strcat(user,".exe");
if((fp=fopen(user,"rb"))==NULL){
return false;
}
else{
UFD *ufd = getspace(UFD);
while(1){//在此用户目录下查找匹配文件
fread(ufd,sizeof(UFD),1,fp);
if(feof(fp)){
fclose(fp);return false;
}
if((strcmp(ufd->filename,buffer))==0){//找到要写入新的长度的文件
strcpy(outfile,"outfilelocate.exe");
if((fp1=fopen(outfile,"wb+"))==NULL){
cout<<"\n错误:写入文件长度出错_3。";
// fclose(fp1);
fclose(fp);return false;
}
else{
fclose(fp);
fp=fopen(user,"rb");//文件指针从新指向此用户文件信息管理模块开头
while(1){
fread(ufd,sizeof(UFD),1,fp);
if(feof(fp))
break;
if(strcmp(ufd->filename,buffer)==0){//找到匹配的文件
if(BOOL) ufd->length+=len; //在文件末追加内容的操作
else ufd->length =len; //覆盖原文件内容
}
fwrite(ufd,sizeof(UFD),1,fp1);
}
fclose(fp);fclose(fp1);
remove(user);
rename(outfile,user);
return true;
}
}
}
}
}
void WriteLengthToFile(int Len,bool BOOL)//将文件长度写入文件管理模块中
{//因为当前用户可以对其它用户的文件进行操作(只要权限允许)
//所以应该在整个文件系统目录下查找该文件的位置
FILE *fp;
if((fp=fopen("LOGIN.exe","rb"))==NULL){//不能打开文件
cout<<"\n写入文件长度错误_1!";
// fclose(fp);
return;
}
else{
elseuser = getspace(MFD);
while(1){
fread(elseuser,sizeof(MFD),1,fp);
if(feof(fp))
break;
else{
if(WriteRight(Len,BOOL)){//查看是否已经正确地写入到该文件信息中
fclose(fp);return;
}
}
}
cout<<"\n写入文件长度错误_2!";
fclose(fp);return;
}
}
void WriteFile()//向文件写入信息的操作
{
if(!QueryMod(true))//查询当前用户对该文件是否有写权
return;//对该文件没有写权则返回
char ch;
int i=0;
FILE *fp;
if((fp=fopen(buffer,"r"))==NULL)//查询该文件是否存在
{
cout<<"\n该文件不存在,请创建该文件后再写入。";
// fclose(fp);
return;
}
fclose(fp);
cout<<"\n请选择写入方式:"<<endl;
cout<<" 1、覆盖原文件 2、在原文件末尾写入 3、取消"<<endl;
cin>>ch;
cout<<"开始输入正文:"<<endl;
switch(ch)
{
case '1'://覆盖原文件
if((fp=fopen(buffer,"w"))==NULL)
cout<<"\n文件打开失败。";
else
{
ch=getchar();
while(ch!='#')//将新的文件内容写入到文件的磁盘位置中
{
i++;
fputc(ch,fp);
ch=getchar();
}
}
fclose(fp);
WriteLengthToFile(i,false);//将文件长度写入文件管理模块
break;
case '2':
if((fp=fopen(buffer,"a"))==NULL)
cout<<"\n文件打开失败。";
else
{
ch=getchar();
while(ch!='#')//将新的文件内容写入到文件的磁盘位置中
{
i++;
fputc(ch,fp);
ch=getchar();
}
}
fclose(fp);
WriteLengthToFile(i,true);//将文件长度写入文件管理模块
break;
default:
break;
}
}
void ReadFile()//读文件函数
{
if(!QueryMod(false))//查询当前用户是否有权读该文件
return;//没有读权,则返回
FILE *fp;
if((fp=fopen(buffer,"r"))==NULL)//打开该文件
{
cout<<buffer;
cout<<"\n该文件不存在。";
return;
}
else{
char ch;
ch=fgetc(fp);
while(ch!=EOF)//将该文件信息逐一输出到终端
{
putchar(ch);
ch=fgetc(fp);
}
cout<<endl;
}
fclose(fp);
}
void ChangeMod()//修改某文件的执行权限
{
int mod=40;
FILE *fp,*infile,*outfile;
char in[50],out[50];
UFD *ufd = getspace(UFD);
strcpy(in,curuser->username);
strcat(in,".exe");
strcpy(out,"outfilelocate.exe");
if((fp=fopen(in,"rb"))==NULL){
// fclose(fp);
cout<<"\n操作出现错误,对此我们表示歉意!";return;
}
else{
while(1){//查看该文件是否在当前用户的注册目录下
//任何用户无权修改不是自己目录下的文件的权限值
fread(ufd,sizeof(UFD),1,fp);
if(feof(fp)){//在当前目录下找不到该文件,说明该用户无权修改该文件权限
cout<<"\n你没有权限对文件 "<<buffer<<" 执行该操作!";
fclose(fp);return;
}
if(strcmp(ufd->filename,buffer)==0){//找到该文件,继续操作
fclose(fp);break;
}
}
}
bool flag1=true;
while(flag1)
{
cout<<"\n输入文件 "<<buffer<<" 的新的权限值:";
cin>>mod;//输入权限值
if(mod<30 || mod>33)
{//确保输入的权限值正确
cout<<"\n错误:权限值必须在30~33之间";
continue;
}
else{
char ch;
switch(mod){//告诉用户对该文件权限修改的结果,以便用户确认
case 30:
cout<<"\n当前权限设置:其他用户对"<<buffer<<"既没读权也没写权!";
break;
case 31:
cout<<"\n当前权限设置:其他用户对"<<buffer<<"没读权但有写权!";
break;
case 32:
cout<<"\n当前权限设置:其他用户对"<<buffer<<"有读权但没写权!";
break;
case 33:
cout<<"\n当前权限设置:其他用户对"<<buffer<<"既有读权也有写权!";
break;
default: break;
}
cout<<"\n确认按'Y',取消按'N':";
cin>>ch;
switch(ch){
case 'Y':
case 'y':flag1=false;break;
default: flag1=true;
}
}
}
//更新文件信息管理模块,相关操作类似上面,不在赘述
if((infile=fopen(in,"rb"))==NULL){
cout<<"\n操作出现错误,对此我们表示歉意!";fclose(infile);
return;
}
else{
if((outfile=fopen(out,"wb+"))==NULL){
cout<<"\n操作出现错误,对此我们表示歉意!";
fclose(infile);//fclose(outfile);
return;
}
else{
while(1)
{
fread(ufd,sizeof(UFD),1,infile);
if(feof(infile))
break;
if((strcmp(ufd->filename,buffer))==0)
ufd->safecode=mod;
fwrite(ufd,sizeof(UFD),1,outfile);
}
fclose(infile);fclose(outfile);
remove(in);
rename(out,in);
}
}
}
void Execute(int i,int len,int cmdset)//执行命令函数
{
int j=0;
for(;i<len;i++)
{
if(cmd[i]=='>'||cmd[i]==' ')
break;
buffer[j]=cmd[i];j++;
}
buffer[j]='\0';
strcat(buffer,".txt");
switch(cmdset)
{
case 1: //退出
ByeFile(true);
break;
case 2: //改变文件操作权限
if((strcmp(buffer,".txt"))==0){
cout<<"\n输入命令出错!";
return;
}
ChangeMod();
break;
case 3: //删除用户
DeleteUser();
break;
case 4: //创建文件
if((strcmp(buffer,".txt"))==0){
cout<<"\n输入命令出错!";
return;
}
CreatFile();
break;
case 5: //删除文件
if((strcmp(buffer,".txt"))==0){
cout<<"\n输入命令出错!";
return;
}
DeleteFile();
break;
case 6: //列出该用户所有文件清单
ListAllFile();
break;
case 7: //打开文件
if((strcmp(buffer,".txt"))==0){
cout<<"\n输入命令出错!";
return;
}
OpenFile();
break;
case 8: //读文件
if((strcmp(buffer,".txt"))==0){
cout<<"\n输入命令出错!";
return;
}
ReadFile();
break;
case 9: //写文件
if((strcmp(buffer,".txt"))==0){
cout<<"\n输入命令出错!";
return;
}
WriteFile();
break;
default:
break;
}
}
void Command()//读取用户输入的命令,并将其转换成系统能识别的命令
{
int len = 0,i,j;
int cmdset;
while(1)
{
cmdset = 0;
cout<<"\nrun\\";
cin>>cmd;
len = strlen(cmd);
i=0;j=0;
while(cmd[i]=='>'||cmd[i]==' '){i++;}//过滤空格键和'>'
for(;i<len;i++)
{
if(cmd[i]=='>' || cmd[i]==' ' || i==len-1)
{
if(cmd[i]=='>' || cmd[i]==' ')
buffer[j] = '\0';
else
if(i==len-1)
{
buffer[j]=cmd[i];
buffer[j+1]='\0';
}
i++;
j=0;
int low=1,mid,high=keynum-1;
bool BOOL = false;
while(low<=high){//找到该命令关键字的内部识别码
mid=(low+high)/2;
if (strcmp(buffer,KWORD[mid])<=0) high=mid-1;
if (strcmp(buffer,KWORD[mid])>=0) low=mid+1;
if(strcmp(buffer,KWORD[mid])==0){
BOOL = true;
break;
}
}
if(!BOOL)
{
cout<<"\n"<<buffer<<"不是系统定义的命令...";
cmdset = 0; break;
}
else {cmdset = mid;break;}
}
else{
buffer[j] = cmd[i];
j++;
}
}
if(cmdset == 0) continue;
while(cmd[i]=='>'||cmd[i]==' '){i++;}//过滤空格键和'>'
buffer[0]='\0';
Execute(i,len,cmdset); //执行该命令
}
}
void main()
{
while(1){
int SELETE = LoginDisplay();
if(SELETE==0)
exit(0);
bool BOOL = Login(SELETE);//用户登陆,或者注册函数
if(BOOL)
{
KeyWord(); //初始化命令关键字
DisplayUFD();//打印用户目录下的文件
Command(); //命令行操作
}
}
}
五.调试结果:
1)系统界面如下:
2)创建新用户:如果你以前还没有注册,则可以先选择2,创建一个用户.
3)创建用户后,可以用create>xiao命令建立一个名为xiao的text文件.并可以用list查看文件的信息(xiao.txt是文件名,0表示文件当前的长度为0,30用二进制表示为1100,表示当前用户有读写权,而其它用户没有读权也没有写权)。
4)用write>xiao命令向这个文件写信息,选择1或是2,输入信息如下: ( 注意:所有信息输入完后要以‘#’号键作为结束标志。)
5)用read>xiao命令读文件中的内容.
6)此时再write>xiao命令向这个文件写信息,选择1,输入信息,并用read>xiao查看,结果如下:
7)还可以用open>xiao这个命令打开文件,发现文件内容变为:
8)以上是文件的基本操作,要懂得这个系统的更多功能,用户只需亲自使用这个界面友好,提示众多的软件几分钟,就可以很自由的操作这个软件了.所以这里就不一一介绍了.
六.心得体会:
此次实验做的比较全面,编译也是用C++builder.主要是因为操作系统的课程设计也是类似的文件系统管理,可重新做类似的事,兴趣没有这么高了,不过还是有新的收获的.
实验二文件系统实验报告一实验简介本实验要求在假设的IO系统之上开发一个简单的文件系统这样做既能让实验者对文件系统有整体了解又避免了…
目录1课程设计简介111课程设计的目的112课程设计内容12数据结构的设计221预定义222结构体223全局变量和函数23功能模块…
昆明理工大学信息工程与自动化学院学生实验报告201201学年第二学期课程名称操作系统开课实验室年月日一实验目的用C或C语言编写和调…
操作系统课程设计报告简单文件系统的实现专业班级姓名学号老师一课程设计的目的1通过具体的文件存储空间的管理文件的物理结构目录结构和文…
实验四文件系统实验一目的要求1用高级语言编写和调试一个简单的文件系统模拟文件管理的工作过程从而对各种文件操作命令的实质内容和执行过…
操作系统课程设计实验报告nachos专业计算机科学与技术班级20xx级2班姓名李霜学号20xx00130082目录Laborato…
实验项目案例名学生饭卡管理系统一实验目的能够正确运用系统设计的过程与方法结合一个模拟课题复习巩固管理信息系统中系统设计知识提高系统…
操作系统实验报告操作系统实验报告题目班级文件管理系统20xx年12月21日1操作系统实验报告目录一实践内容311实验内容32实验原…
Linux课程设计报告学院信息学院专业班级08级网络二班姓名学号实验目的1通过课程设计对操作系统基本原理进行更深入的认识以Linu…
操作系统课程设计实验报告姓名学号班级地点20xx年月日任务说明共完成四个任务任务一IO系统调用开销比较任务二实现一个简单的shel…