实验四 文件系统实验
一 . 目的要求
1、用高级语言编写和调试一个简单的文件系统,模拟文件管理的工作过程。从而对各种文件操作命令的实质内容和执行过程有比较深入的了解。
2、要求设计一个 n个用户的文件系统,每次用户可保存m个文件,用户在一次运行中只能打开一个文件,对文件必须设置保护措施,且至少有Create、delete、open、close、read、write等命令。
二 . 例题:
1、设计一个10个用户的文件系统,每次用户可保存10个文件,一次运行用户可以打开5个文件。
2、程序采用二级文件目录(即设置主目录[MFD])和用户文件目录(UED)。另外,为打开文件设置了运行文件目录(AFD)。
3、为了便于实现,对文件的读写作了简化,在执行读写命令时,只需改读写指针,并不进行实际的读写操作。
4、算法与框图:
①因系统小,文件目录的检索使用了简单的线性搜索。
②文件保护简单使用了三位保护码:允许读写执行、对应位为 1,对应位为0,则表示不允许读写、执行。
③程序中使用的主要设计结构如下:
主文件目录和用户文件目录( MFD、UFD)
打开文件目录( AFD)(即运行文件目录)
文件系统算法的流程图如下:
三 . 实验题:
1、增加 2~3个文件操作命令,并加以实现。(如移动读写指针,改变文件属性,更换文件名,改变文件保护级别)。
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <conio.h>
#define MAXSIZE 100
#define ADDSIZE 50
#define PT elem+l-> length
#define N 4
typedef struct term{/*班级和学期的结构体*/
char class1[10];
char term1[10];
}term;
typedef struct student{/*学生成绩信息的结构体*/
term st;/*班级和学期结构体放于此结构体中*/
char num[10];
char name[12];
float course[4];
float total;
float average;
int bit;
}lnode,*stu;
typedef struct{
lnode *elem;/*指向上个结构体的指针*/
int size;/*最大能放lnode结构体成员的个数*/
int length;/*当前长度*/
}sqack,*sq;
sqack *l;
void init(void)/*动态分配存储空间*/
{
l-> elem=(stu)malloc(MAXSIZE*sizeof(lnode));
l-> length =0;
l-> size=MAXSIZE;
}
void input(void)/*输入学生的信息*/
{
lnode *newbase,*p;
char cla[10],ter[10],ch;
int n,i;
if(l-> length> =l-> size){
newbase=(stu)realloc(l-> elem,(l-> size +ADDSIZE)*sizeof(lnode));/*追加存储空间*/
l-> elem =newbase;
l-> size +=ADDSIZE;
}
p=l-> elem;
do
{
printf( "输入班级和学期(学期用这种格式,如20##年上学期 20## 1,20##年下学期 20## 2;先输入班级,回车后再输入学期)\n ");
gets(cla);
gets(ter);
printf( "要输入多少个名单? ");
scanf( "%d ",&n);
printf( "输入学生的成绩\n学号\t姓名\t科目1\t科目2\t科目3\t科目4\n ");
for(i=0;i <n;i++)
{
scanf( "%s%s%d%d%d%d ",p-> num ,p-> name,p-> course[0],p-> course[1],p-> course[2],p-> course[3]);
strcpy(p-> st.class1,cla);
strcpy(p-> st.term1,ter);
++l-> length ;
}
printf( "要继续吗?(y/n) ");
ch=getchar();}while(ch== 'Y '||ch== 'y ');
}
void change()/*修改学生的信息*/
{
lnode *p;
lnode e;
int flag=1,i;
char s1[10],num1[10];
printf( "输入学期和学号(输入学期以后按回车再输入学号):\n ");
gets(s1);
gets(num1);
p=l-> elem ;
while(p <=(l-> elem+l-> length ) && flag==1)/*查找要修改的学生的信息*/
{
if(strcmp(p-> num,num1)==0&&strcmp(p-> st.term1,s1)==0)
flag=0;/*找到了*/
p++;
}
p--;
if(flag==1) printf( "找不到此学号!\n ");
printf( "%s %s ",p-> num,p-> name);
for(i=0;i <N;i++)
printf( "%d ",p-> course[i]);
printf( "\n ");
printf( "输入修改信息\n ");
scanf( "%s%s%s%s ",e.st.class1,e.st.term1,&e.num,e.name);
for(i=0;i <N;i++)
scanf( "%d ",&e.course[i]);
*p=e;
}
void same(char *t1,char *t2,lnode *t,int *k) /*把学期和班级相同的学生信息放在结构体数组tt中*/
{
int i=0;
lnode *p,*q;
q=t;
p=l-> elem ;
while(p <=l-> elem+l-> length )
{
if(strcmp(p-> st.term1,t1)==0&&strcmp(p-> st.class1 ,t2)==0)
{
*q=*p;q++;
i++;
}
p++;
}
*k=i;
}
void sort(lnode *p,int *k)/*按学生成绩从高到低排序函数*/
{
int i;
lnode *q,temp;
for(q=p;q <p+ *k;q++)
{
q-> total =0;
for(i=0;i <N;i++)
q-> total =q-> total +q-> course [i];
q-> average =q-> total /N;
}
for(i=0;i <*k-1;i++)
for(q=p;q <p+*k-1-i;q++)
if(q-> total <(q+1)-> total)
{
temp=*q;*q=*(q+1);*(q+1)=temp;
}
}
void print(lnode *q,int *k)/*输出学生的成绩*/
{
lnode *p;
p=q;
for(p=q;p <q+*k;p++)
{
printf( "%s %s ",p-> num,p-> name);
for(int i=0;i <N;i++)
printf( "%d ",p-> course[i]);
printf( "%d %f ",p-> total,p-> average);
printf( "\n ");
}
}
void stat()/*统计学生的成绩*/
{
lnode tt[50];
char ter[10],clas[10];
int i,k;
printf( "请输入学期和班级(输入学期后按回车再输入班级):\n ");
for(i=0;ter[i]!= '\n ';i++)
ter[i]=getchar();
for(i=0;clas[i]!= '\n ';i++)
clas[i]=getchar();
same(ter,clas,tt,&k);/*把学期和班级相同的学生信息放在结构体数组tt中*/
sort(tt,&k);/*按学生成绩从高到低排序函数*/
print(tt,&k);/*输出学生的成绩*/
}
void search1()/*按学号查*/
{
lnode *p;
char ter1[10];
int i,flag=1;
p=l-> elem;
printf( "输入学号: ");
gets(ter1);
for(p=l-> elem;p <l-> PT;p++)
{
if(strcmp(p-> num,ter1)==0)
{
flag=0;
printf( "%s %s ",p-> st.term1,p-> st.class1);
printf( "%s %s ",p-> num,p-> name);
for(i=0;i <N;i++)
printf( "%d ",p-> course[i]);
printf( "%d %3.1f ",p-> total,p-> average);
printf( "\n ");
}
}
if(flag) printf( "没有找到! ");
}
void search2()/*按姓名查*/
{
lnode *p;
char ter1[10];
int i,flag=1;
p=l-> elem;
printf( "输入姓名: ");
gets(ter1);
for(p=l-> elem;p <l-> PT;p++)
{
if(strcmp(p-> name,ter1)==0)
{
flag=0;
printf( "%s %s ",p-> st.term1,p-> st.class1);
printf( "%s %s ",p-> num,p-> name);
for(i=0;i <N;i++)
printf( "%d ",p-> course[i]);
printf( "%d %f ",p-> total,p-> average);
printf( "\n ");
}
}
if(flag) printf( "没有找到! ") ;
}
void search()/*查找学生的成绩*/
{
char ch;
do
{
printf( "1 按学号查询\n2按姓名查询\n ");
ch=getchar();
switch(ch)
{
case '1 ':
search1();
break;
case '2 ':
search2();
break;
default:
printf( "错误!\n ");
}
printf( "要继续查找吗?(y/n) ");
ch=getchar();
} while(ch== 'y ' || ch== 'Y ');
}
void fail()/*查找不及格及学生名单*/
{
int i;
lnode *p;
for(p=l-> elem;p <l-> PT;p++)
{
for(i=0;i <N;i++)
if(p-> course[i] <60)
{
printf( "%s %s ",p-> st.class1,p-> st.term1);
for(i=0;i <N;i++)
printf( "%d ",p-> course[i]);
printf( "%d %f ",p-> total,p-> average);
printf( "\n ");}}
}
void output()/*按班级输出学生的成绩单*/
{
lnode tt[50];
int k;
char clas[10],ter1[10];
printf( "输入要查询的班级和学期(输入班级后按回车输入学期):\n ");
gets(clas);
gets(ter1);
same(ter1,clas,tt,&k);/*把学期和班级相同的学生信息放在结构体数组tt中*/
print(tt,&k);/*输出学生的成绩*/
}
int main()
{
char ch;
do
{
printf( "请选择:\n ");
printf( "1 对学生成绩的录入\n2 对学生成绩的修改\n3 统计学生成绩\n4 查询学生成绩\n5查找不及格科目及学生名单\n6 按班级输出学生成绩单\n ");
ch=getchar();
switch(ch)
{
case '1 ': input();break;
case '2 ':change();break;
case '3 ':stat();break;
case '4 ':search();break;
case '5 ':fail();break;
case '6 ':output();break;
default:printf( "错误!\n ");
}
printf( "要继续吗?(y/n) ");
ch=getchar();
}while(ch== 'y '||ch== 'Y ');
return 0;
getch();
}
2、编一个通过屏幕选择命令的文件管理系统,每屏要为用户提供足够的选择信息,不需要打入冗长的命令。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//主文件结构体
struct MasterFile{
char username[20]; //用户名
char password[20]; //用户名密码
char flag; //标志
struct MasterFile *next;
};
//用户文件结构体
struct UserFile{
int fnum; //文件编号
char fname[20]; //文件名
int flength; //文件长度
char flag; //标志
char fpw[20]; //文件保护码
struct UserFile *link;
};
//全局变量
int shoudsave; //存储标记
int usingnum; //当前用户标记
struct MasterFile MFD[20]; //主目录
struct UserFile UFD[20][20]; //用户目录
//寻找主目录空闲区
struct MasterFile*MoveMFDToLast()
{
for(int i=0;i<20;i++){
if(MFD[i].flag==0)
usingnum=i;
return &MFD[i];
}
return NULL;
}
//查找用户
struct MasterFile*SearchMFD(char str[]){
for(int i=0;i<20;i++){
if(strcmp(str,MFD[i].username)==0){
usingnum=i;
return &MFD[i];
}
}
return NULL;
}
//寻找用户目录空闲区
struct UserFile *MoveUFDToLast(){
for(int i=0;i<20;i++){
if(UFD[usingnum][i].flag==0)
return &UFD[usingnum][i];
}
return NULL;
}
//查找用户文件
struct UserFile *SearchUFD(int num){
for(int i=0;i<20;i++){
if(UFD[usingnum][i].fnum==num)
return &UFD[usingnum][i];
}
return NULL;
}
//删除用户文件目录
void LeftMoveUFD(int num){
for(int i=0;i<20;i++){
if(UFD[usingnum][i].fnum==num){
for(int j=i;j<19;j++){
UFD[usingnum][i].flag=UFD[usingnum][i+1].flag;
UFD[usingnum][i].flength=UFD[usingnum][i+1].flength;
strcpy(UFD[usingnum][i].fname,UFD[usingnum][i+1].fname);
UFD[usingnum][i].fnum=UFD[usingnum][i+1].fnum;
strcpy(UFD[usingnum][i].fpw,UFD[usingnum][i+1].fpw);
UFD[usingnum][i].link=UFD[usingnum][i+1].link;
}
}
}
}
//用户登陆
void Login(){
char flag1,flag2,flag3;
char str1[20],str2[20],str3[20],str4[20];
struct MasterFile *p;
printf("你是已有用户吗(y/n)?");
scanf("%s",&flag1);
if(flag1=='n'){ //新用户登录
printf("请创建新的用户:(y/n)");
scanf("%s",&flag2);
if(flag2=='n'){
printf("你已退出了系统!\n");
exit(1);
}else{
printf("请输入你的用户名:");
scanf("%s",&str1);
printf("请输入口令:");
scanf("%s",&str2);
p=MoveMFDToLast();
strcpy(p->username,str1);
strcpy(p->password,str2);
p->flag=1;
printf("%d",MFD[usingnum].flag);
p->next=NULL;
shoudsave=1; //存储标记
}
}else{ //旧用户登录
while(1){
printf("请输入你的用户名:"); //输入用户名
scanf("%s",&str3);
p=SearchMFD(str3);
if(p==NULL){
printf("对不起,你输入的用户名不存在!\n");
printf("继续(y)还是放弃(n)?");
scanf("%s",&flag3);
if(flag3=='y') continue;
else{
printf("你已退出了系统!\n");
exit(1);
}
}else{
while(1){
printf("请输入口令:"); //输入口令
scanf("%s",&str4);
if(strcmp(str4,p->password)!=0){
printf("对不起,你输入的口令不正确,请重新输入.\n");
continue;
}else break;
}
}break;
}
}
}
//菜单
void menu(){
printf("\n********************************************************************************");
printf("\t1列文件目录\t\t\t\t\t2创建文件\n");
printf("\t3删除文件\t\t\t\t\t4读文件\n");
printf("\t5写文件\t\t\t\t\t\t0退出系统\n");
printf("********************************************************************************\n");
}
//列文件目录
void Dir(){
if(MFD[usingnum].next==0)
printf("目前你不存在任何文件!\n");
else{
for(int i=0;i<20;i++){
if(UFD[usingnum][i].flag==1)
printf("文件编号\t%d\t文件名\t%s\t文件长度\t%d\t保护码\t%s\n",UFD[usingnum][i].fnum,UFD[usingnum][i].fname,UFD[usingnum][i].flength,UFD[usingnum][i].fpw);
}
}
}
//创建文件
void Create(){
FILE *fp;
int num;
struct UserFile *f;
char str1[20],str2[20];
printf("请输入你要创建的文件名:"); //输入文件信息
scanf("%s",&str1);
printf("请输入文件编号:");
scanf("%d",&num);
printf("请输入文件保护码:");
scanf("%s",&str2);
fp=fopen(str1,"w"); //创建文件
f=MoveUFDToLast(); //寻找用户目录空闲区
if(&UFD[usingnum][0]==f) //连接主目录
MFD[usingnum].next=(struct MasterFile*)f;
f->link=(struct UserFile*)fp; //设置用户目录
MFD[usingnum].next=(struct MasterFile*)&UFD[usingnum][0];
strcpy(f->fname,str1);
strcpy(f->fpw,str2);
f->fnum=num;
f->flength=0;
f->flag=1;
fclose(fp);
shoudsave=1; //设置存储标记
printf("文件已创建!\n");
}
//删除文件
void Delete(){
struct UserFile *f;
int num;
printf("请输入你要删除的文件编号:");
scanf("%d",&num);
f=SearchUFD(num); //查找用户文件
if(f==NULL) {
printf("你要删除的文件不存在!\n");
}else{
LeftMoveUFD(num); //删除用户文件目录
printf("文件已删除!\n");
}
shoudsave=1; //设置存储标记
}
//读文件
void Read(){
char ch;
struct UserFile *f;
FILE *fp;
int num;
printf("请输入你要读的文件的编号:");
scanf("%d",&num);
f=SearchUFD(num); //查找文件
if(f==NULL){
printf("你输入的文件不存在!\n");
}else{
if((fp=fopen(f->fname,"r"))==NULL){ //打开指定文件
printf("不能打开该文件!\n");
exit(0);
}
}
ch=fgetc(fp); //输出文件内容
while(ch!=EOF){
putchar(ch);
ch=fgetc(fp);
}
printf("\n");
fclose(fp); //关闭文件
printf("文件已读完毕!\n");
}
//写文件
void Write(){
char ch;
struct UserFile *f;
FILE *fp;
int num;
printf("请输入你要写的文件的编号:");
scanf("%d",&num);
f=SearchUFD(num); //查找文件
if(f==NULL){
printf("你输入的文件不存在!\n");
}else{
if((fp=fopen(f->fname,"wr"))==NULL){ //打开指定文件
printf("不能打开该文件!\n");
exit(0);
}
}
printf("请按字符输入内容(以'#'表示结束符)"); //写入文件
scanf("%s",&ch);
while(ch!='#'){
fwrite(&ch,1,1,fp);
scanf("%s",&ch);
}
fclose(fp); //关闭文件
shoudsave=1; //设置存储标记
printf("文件写入完毕!\n");
}
//保存
void Save(){
FILE *fpm,*fpu;
int flag=1,count=0;
fpm=fopen("F:\\MasterFile.txt","wb"); //打开主文件
if(fpm==NULL){
printf("\n提示:重新打开主文件信息文件时发生错误!\n");
exit(1);
}
for(int i=0;i<20;i++)
fwrite(&MFD[i],sizeof(struct MasterFile),1,fpm); //保存主文件目录信息
fclose(fpm);
printf("主文件目录信息保存完毕!\n");
fpu=fopen("F:\\UserFile.txt","wb"); //打开用户文件
if(fpu==NULL){
printf("\n提示:重新打开用户目录信息文件时发生错误!\n");
exit(1);
}
for(int j=0;j<20;j++) //保存用户文件目录信息
fwrite(&UFD[j],sizeof(struct UserFile),20,fpu);
fclose(fpu);
printf("用户文件目录信息保存完毕!\n");
}
//主函数
void main(){
FILE *fpm,*fpu; //文件指针
int sel;
char ch;
char jian;
printf("\t\t\t\t文件管理系统\n\t\t\t\t\n");
fpm=fopen("D:\\MasterFile.txt","rb"); //打开主文件目录信息文件
if(fpm==NULL) {
printf("\n提示:主文件目录信息文件还不存在,是否创建?(y/n)\n");
scanf("%s",&jian);
if(jian=='y'||jian=='Y')
fpm=fopen("D:\\MasterFile.txt","wb"); //创建主文件目录的文件
else exit(0);
}
fpu=fopen("D:\\UserFile.txt","rb"); //打开用户文件目录信息文件
if(fpu==NULL){
printf("\n提示:用户文件目录信息文件还不存在,是否创建?(y/n)\n");
scanf("%s",&jian);
if(jian=='y'||jian=='Y')
fpu=fopen("D:\\UserFile.txt","wb"); //创建用户文件目录的文件
else exit(0);
}
printf("文件正在打开,请稍等...");
for(int i=0;i<20;i++) //读取主文件目录信息
fread(&MFD[i],sizeof(struct MasterFile),1,fpm); //将文件的内容放入接点中
fclose(fpm); // 关闭文件
while(!feof(fpu)){ //读取用户目录文件信息
for(int i=0;i<20;i++){
if(fread(&UFD[i][0],sizeof(struct UserFile),20,fpu)) //将文件的内容放入接点中
MFD[i].next=(struct MasterFile*)&UFD[i][0];
}
}
fclose(fpu); //关闭文件
printf("\n文件已导入完毕!\n");
Login(); //用户登录
while(1) { //菜单操作
menu();
printf("请你选择操作:");
scanf("%d",&sel);
if(sel==0){ //保存文件信息
if(shoudsave==1){
getchar();
printf("\n资料已经改动,是否将改动保存到文件中(y/n)?\n");
scanf("%c",&ch);
if(ch=='y'||ch=='Y')
Save();
}
printf("\n你已经退出系统,再见!\n");
break;
}
switch(sel){
case 1:Dir();
break; //列文件目录
case 2:Create();
break; //创建文件
case 3:Delete();
break; //删除文件
case 4:Read();
break; //读文件
case 5:Write();
break; //写文件
default: printf("你输的选项有误,请重新输入!\n");
break;
}
}
}
3、设计一个树型目录结构的文件系统,其根目录为 root,各分支可以是目录,也可以是文件,最后的叶子都是文件。
#include <stdio.h>
#include <iostream.h>
#include <string.h>
#include <ctype.h>
#include <malloc.h>
#define FILENAME_LEN 21
#define INPUT_LEN 81
#define COMMAND_LEN 11
//结点结构
struct FileNode
{
char filename[FILENAME_LEN];//文件名/目录名
int isdir;//目录文件识别标志
int i_nlink;//文件的链接数
int adr;//文件的地址
struct FileNode *parent, *child;//指向父亲的指针和指向左孩子的指针
struct FileNode *sibling_prev, *sibling_next;//指向前一个兄弟的指针和指向
//后一个兄弟的指针.
};
void Init();//初始化文件树
int ParseCommand();//接受输入的命令并把其分解成操作名和路径文件名
void ExecuteCommand();//执行命令
int cdComd();//处理cd命令
int editComd();//处理edit命令创建文件
int delComd();//处理del命令删除文件
int rdComd();//处理rd命令/删除目录
int dirComd();//处理dir命令
int mdComd();//处理md命令创建目录
int FindPath(char *ph);//寻找参数ph所指向的路径
//从参数Para2中找到要建立或删除的文件、目录名,并把指针指向其父亲结点
int FindFilename(char Para2[]);
struct FileNode* CreateFileNode(char filename[],int isdir,int i_nlink);//创建结点
int GetInput(char* buffer,unsigned int buffer_len);//获取输入
int CheckCommand();//命令检查
int GetDir(int begin,char* path,char* curDir);//获取路径
void Trim(char* str);
struct FileNode * cp, *tp, *root,*upper;
char path[INPUT_LEN-COMMAND_LEN];//记录当前走过的路径
char curpath[INPUT_LEN-COMMAND_LEN],Para1[COMMAND_LEN],
Para2[INPUT_LEN-COMMAND_LEN],tmppath[INPUT_LEN-COMMAND_LEN];
char filename[FILENAME_LEN],dirname[FILENAME_LEN],tmp;
int i,j;
//主函数
int main()
{
printf("<<<*****************09208041 杜耀军 树型目录结构的文件系统*****************>>>\n");
Init();//初始化文件树
while(1)
{
if(ParseCommand())//分解命令
ExecuteCommand();//执行命令
}
}
//执行命令子函数
void ExecuteCommand()
{
int sign;
//根据参数Para1调用相应的功能处理模块
if(strcmp(Para1,"cd")==0)
sign=cdComd(); //cd命令
else if(strcmp(Para1,"edit")==0)
sign=editComd(); //edit命令
else if(strcmp(Para1,"del")==0)
sign=delComd(); //del命令
else if(strcmp(Para1,"dir")==0)
sign=dirComd(); //dir命令
else if(strcmp(Para1,"md")==0)
sign=mdComd(); //md命令
else if(strcmp(Para1,"rd")==0)
sign=rdComd(); //rd命令
else if(strcmp(Para1,"exit")==0)
exit(0); //exit命令
else
printf("命令错误,请重试\n"); //命令输入不正确,报错
}
//创建结点
struct FileNode* CreateFileNode(char filename[],int isdir,int i_nlink)
{
//申请结点空间
struct FileNode* node=(struct FileNode*)malloc(sizeof(struct FileNode));
//相应内容赋初值
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;
return node;
}
//初始化文件树
void Init()
{
struct FileNode *binNode,*usrNode,
*unixNode,*etcNode,*libNode,*userNode,
*binNode2,*liuNode,*sunNode,*ftiNode;
strcpy(path,"/"); //根目录写入当前路径
//创建文件树的结点
binNode=CreateFileNode("bin",1,0);
usrNode=CreateFileNode("usr",1,0);
unixNode=CreateFileNode("unix",0,0);
etcNode=CreateFileNode("etc",1,0);
libNode=CreateFileNode("lib",1,0);
userNode=CreateFileNode("user",1,0);
binNode2=CreateFileNode("bin",1,0);
liuNode=CreateFileNode("liu",1,0);
sunNode=CreateFileNode("sun",1,0);
ftiNode=CreateFileNode("fti",1,0);
cp=tp=root=CreateFileNode("/",1,0);
//结点相应内容赋值
root->parent=NULL;
root->child=binNode;
root->sibling_prev=root->sibling_next=NULL;
binNode->parent=root;
binNode->child=NULL;
binNode->sibling_prev=NULL;
binNode->sibling_next=usrNode;
usrNode->parent=NULL;
usrNode->child=libNode;
usrNode->sibling_prev=binNode;
usrNode->sibling_next=unixNode;
unixNode->parent=NULL;
unixNode->child=NULL;
unixNode->sibling_prev=usrNode;
unixNode->sibling_next=etcNode;
etcNode->parent=NULL;
etcNode->child=NULL;
etcNode->sibling_prev=unixNode;
etcNode->sibling_next=NULL;
libNode->parent=usrNode;
libNode->child=liuNode;
libNode->sibling_prev=NULL;
libNode->sibling_next=userNode;
userNode->parent=NULL;
userNode->child=NULL;
userNode->sibling_prev=libNode;
userNode->sibling_next=binNode2;
binNode2->parent=NULL;
binNode2->child=NULL;
binNode2->sibling_prev=userNode;
binNode2->sibling_next=NULL;
liuNode->parent=libNode;
liuNode->child=NULL;
liuNode->sibling_prev=NULL;
liuNode->sibling_next=sunNode;
sunNode->parent=NULL;
sunNode->child=NULL;
sunNode->sibling_prev=liuNode;
sunNode->sibling_next=ftiNode;
ftiNode->parent=NULL;
ftiNode->child=NULL;
ftiNode->sibling_prev=sunNode;
ftiNode->sibling_next=NULL;
}
//获取文件或目录名,并把指针指向其父亲结点
int FindFilename(char Para2[])
{
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';
else Para2[i]='\0';
j--;
//filename逆转,获得正确的文件或目录名
for(i=0;i<strlen(filename)/2;i++,j--)
{
tmp=filename[i];
filename[i]=filename[j];
filename[j]=tmp;
}
//查找路径
if(strlen(Para2)>0)
{
int sign=FindPath(Para2);
if(sign==0) return 0;
}
return 1;
}
//缓冲区安全输入子函数
//如果输入超过buffer_len,则截取前buffer_len-1长度的输入,
//buffer_len处字符用'/0'代替
int GetInput(char* buffer,unsigned int buffer_len)
{
int count=0;
while(count<buffer_len)
{
if((buffer[count]=getchar())==10)
{
buffer[count]='\0';
return count;
}
count++;
}
while(getchar()!=10);
buffer[buffer_len-1]='\0';
return -1;
}
//分解命令子函数
int ParseCommand()
{
char Inputs[INPUT_LEN];
int i=0,j=0,k=0,ch;
printf("%s>",path);
//获取输入
if(GetInput(Inputs,INPUT_LEN)==-1)
{
printf("输入行太长。\n");
return 0;
}
Para1[0]=Para2[0]='\0';
//获取参数Para1,即操作名
while(Inputs[i]!=' '&&Inputs[i]!='\0' && i<COMMAND_LEN-1)
{
Para1[i]=Inputs[i];
i++;
}//while
Para1[i]='\0';
//输入命令太长
if(i==(COMMAND_LEN-1))return 1;
//获取参数2,即路径文件名
if(Inputs[i]!='\0')
{
while(Inputs[i]==' ' && i<INPUT_LEN-1) i++;
j=0;
while(Inputs[i]!='\0' && i<INPUT_LEN-1)
{
Para2[j]=Inputs[i];
i++; j++;
}
Para2[j]='\0';
}
Trim(Para1);
Trim(Para2);
//将操作名全部转换成小写字母
for(k=0;k<strlen(Para1);k++)
{
ch=tolower((int)Para1[k]);
Para1[k]=ch;
}
return 1;
}
//cd功能处理子函数
int cdComd()
{
if(!CheckCommand())//命令检查
return 0;
if(strcmp(Para2,"..")==0)
{ //对cd ..命令的处理
int i;
while(cp->sibling_prev)
cp=cp->sibling_prev;//找到这一层最左边的结点
if(cp->parent)
{
cp=cp->parent;//找到父亲结点
}
else
{
return 0;
}
//对当前路径进行相应处理
i=strlen(path);
while(path[i]!='/'&& i>0) i--;
if(i!=0)
path[i]='\0';
else
path[i+1]='\0';
}
else
{
FindPath(Para2);//查找路径
}
return 1;
}
//命令格式处理子函数
void Trim(char* str)
{
int begin,end;
char* tmp;
begin=0;
end=strlen(str);
//找到字符串第一个非空格的位置
while(str[begin]==' ' && str[begin]!='\0')begin++;
//去除字符串尾部空格
while(str[--end]==' ');
str[end+1]='\0';
//除去空格
if(begin<end)
{
tmp=(char*)malloc((sizeof(char))*(end-begin+2));
strcpy(tmp,&str[begin]);
strcpy(str,tmp);
free(tmp);
}
}
//获取当前目录名子函数
int GetDir(int begin,char* path,char* curDir)
{
int i=0;
int len=strlen(path);
while(!((path[begin]=='\\' )|| (path[begin]=='/'))&&begin<len)
{
curDir[i++]=path[begin++];
}
curDir[i]='\0';
Trim(curDir);
return begin+1;
}
//查找路径子函数
int FindPath(char *ph)
{
struct FileNode *tp,*temp;
char oldpath[INPUT_LEN-COMMAND_LEN];
int i=0;
int sign=1;
if(strcmp(ph,"/")==0)
{ //ph是根目录
cp=root;
strcpy(path,"/");
return 1;
}
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");
return 0;
}
}
}
while(i<=strlen(ph)&& cp)//继续查找指定路径,如遇到文件则报错
{
int j=0;
if(ph[i]=='/'&& cp->child)
{
i++;//略过 '/'
if(cp->isdir)
cp=cp->child;//继续查找下级目录
else
{
printf("路径错误!\n");
return 0;
}
strcat(path,"/");
}
//curpath 记录当前要找的路径名
while(ph[i]!='/'&& i<=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");
return 0;
}
strcat(path,cp->filename);
}
if(strcmp(cp->filename,curpath)!=0 || cp==NULL)
{
strcpy(path,oldpath);
cp=temp;
printf("输入路径错误\n");
return 0;
}
}
return 1;
}
//创建文件子函数
int editComd()
{
char tmp;
struct FileNode * temp=CreateFileNode("",0,0);
int sign;
struct FileNode *tp;
//路径不能为空
if(strlen(Para2)==0)
{
printf("\n命令格式有错误.\n");
return 0;
}
//长度检查
if(strlen(Para2)>50)
{
printf("\n文件名过长\n");
return 0;
}
//格式检查
if (!(isalpha(Para2[0])||Para2[0]=='_'||Para2[0]=='\0'||Para2[0]=='/'))
{
printf("文件名格式有错!\n");/* 文件首字母可以为'字母'或'数字'或'_'或'/'或'回车'*/
return 0;
}
//获取文件名
sign=FindFilename(Para2);
if(sign==0)
return 0;
if(cp->isdir!=1)//如当前指针指向的是文件,则报错
{
printf("you cannot edit a file in under a file!\n");
return 0;
}
//创建文件结点,并插入到指定目录下
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_next=NULL;
}
else
{ temp=cp;
//用temp找到新结点插入处
temp=temp->child;
while(temp->sibling_next )//find the last sibing node
{
temp=temp->sibling_next;
if(strcmp(temp->filename,filename)==0&&temp->isdir==0)
{
printf("此文件名已存在\n");//重名报错
return 0;
}
}//找到了最后一个结点
temp->sibling_next=tp;
tp->parent=NULL;
tp->child=NULL;
tp->sibling_prev=temp;
tp->sibling_next=NULL;
}
return 1;
}
//创建目录子函数
int mdComd()
{
char tmp;
int sign;
struct FileNode * temp, *tp;
temp=CreateFileNode("",1,0);
//参数不能为空
if(strlen(Para2)==0)
{
printf("\n命令格式有错误.\n");
return 0;
}
//长度检查
if(strlen(Para2)>50)
{
printf("\n目录名过长\n");
return 0;
}
//格式检查
if (!(isalpha(Para2[0])||Para2[0]=='_'||Para2[0]=='\0'||Para2[0]=='/'))
{
printf("目录名格式有错!\n");/* 目录首字母可以为'字母'或'数字'或'_'或'/'或'回车'*/
return 0;
}
//获取目录名
sign=FindFilename(Para2);
if(sign==0) return 0;
//若当前指针指向的是文件,则报错
if(cp->isdir!=1)
{
printf("you cannot make a directory in under a file!\n");
return 0;
}
//创建目录结点,并插入到指定目录下
tp=CreateFileNode(filename,1,0);
if(cp->child==NULL)
{ tp->parent=cp;
tp->child=NULL;
cp->child=tp;
tp->sibling_prev=NULL;
tp->sibling_next=NULL;
}
else
{ temp=cp;
//用temp找到新结点插入处
temp=temp->child;
while(temp->sibling_next )//find the last sibing node
{
temp=temp->sibling_next;
if(strcmp(temp->filename,filename)==0&&temp->isdir==1)
{
printf("此文件名已存在\n");//重名报错
return 0;
}
}//找到了最后一个结点
temp->sibling_next=tp;
tp->parent=NULL;
tp->child=NULL;
tp->sibling_prev=temp;
tp->sibling_next=NULL;
}
return 1;
}
//删除文件子函数
int delComd()
{
char tmp;
int sign;
struct FileNode *temp;
//参数不能为空
if(strlen(Para2)==0)
{
printf("\n命令格式有错误.\n");
return 0;
}
//获取文件名
sign=FindFilename(Para2);
if(sign==0) return 0;
//用temp指向要删除的结点
if(cp->child)
{
temp=cp->child;
while(temp->sibling_next && (strcmp(temp->filename,filename)!=0 || temp->isdir!=0))
temp=temp->sibling_next;
if(strcmp(temp->filename,filename)!=0)
{
printf("ERROR!该命令只能删除文件,不可删除目录!\n");
return 0;
}
}
else
{
printf("不存在该文件!\n");
return 0;
}
//要删除的不能是目录
if(temp->isdir!=0)
{
printf("ERROR!该命令只能删除文件,不可删除目录!\n");
return 0;
}
//如仍有用户使用该文件,则不能删除
if(temp->i_nlink!=0)
{
printf("还有用户共享了该文件,不能删除!\n");
return 0;
}
//删除工作
if(temp->parent==NULL)//不是第一个孩子
{
temp->sibling_prev->sibling_next=temp->sibling_next;
if(temp->sibling_next)//处理是最后一个兄弟的情况
temp->sibling_next->sibling_prev=temp->sibling_prev;
temp->sibling_prev=temp->sibling_next=NULL;
}//if
else//第一个孩子
{
if(temp->sibling_next)//处理是最后一个兄弟的情况
temp->sibling_next->parent=temp->parent;
temp->parent->child= temp->sibling_next;
}//else
free(temp);
return 1;
}
//命令检查子函数
int CheckCommand()
{
if(strlen(Para2)==0)
{
printf("命令语法不正确。\n");
return 0;
}
return 1;
}
//删除目录子函数
int rdComd()
{
char tmp;
struct FileNode *temp;
char cmd[2];
//命令检查
if(!CheckCommand())
return 0;
//获取目录名
if(!FindFilename(Para2))
return 0;
//用temp指向要删除的结点
if(cp->child)
{
temp=cp->child;
while(temp->sibling_next && (strcmp(temp->filename,filename)!=0|| temp->isdir!=1))
temp=temp->sibling_next;
if(strcmp(temp->filename,filename)!=0)
{
printf("不存在该目录!\n");
return 0;
}
}
else
{
printf("不存在该目录!\n");
return 0;
}
//要删除的不能是文件
if(temp->isdir!=1)
{
printf("ERROR!该命令只能删除目录,不可删除文件!\n");
return 0;
}
//若要删除的目录不为空,则提示用户是否删除
if(temp->child)
{
printf("\n该目录不为空,您确定要删除吗? Y/N \n");
GetInput(cmd,2);
if(strcmp(cmd,"n")==0||strcmp(cmd,"N")==0)
return 0;
}
//删除工作
if(temp->parent==NULL)//不是第一个孩子
{
temp->sibling_prev->sibling_next=temp->sibling_next;
if(temp->sibling_next)//处理是最后一个兄弟的情况
temp->sibling_next->sibling_prev=temp->sibling_prev;
temp->sibling_prev=temp->sibling_next=NULL;
}//if
else//第一个孩子
{
if(temp->sibling_next)//处理是最后一个兄弟的情况
temp->sibling_next->parent=temp->parent;
temp->parent->child= temp->sibling_next;
}//else
free(temp);
return 1;
}
//显示目录子函数
int dirComd()
{
if(strlen(Para2)>0)
{
int sign=FindPath(Para2);//查找路径
if(sign==0)
{
return 0;
}
else
{
printf("\n%s>", path);
}
}
if(cp!=root)
printf(" <DIR> %s\n","..");
if(cp->child==NULL)
{
return 0;//指定目录为空
}
tp=cp;
//指定目录不为空,显示其所有子目录及文件名
tp=tp->child;
while(tp)
{
if(tp->isdir)
printf(" <DIR> %s\n",tp->filename);
else
printf(" <FILE> %s\n",tp->filename);
tp=tp->sibling_next;
}
}
实验二文件系统实验报告一实验简介本实验要求在假设的IO系统之上开发一个简单的文件系统这样做既能让实验者对文件系统有整体了解又避免了…
目录1课程设计简介111课程设计的目的112课程设计内容12数据结构的设计221预定义222结构体223全局变量和函数23功能模块…
昆明理工大学信息工程与自动化学院学生实验报告201201学年第二学期课程名称操作系统开课实验室年月日一实验目的用C或C语言编写和调…
操作系统课程设计报告简单文件系统的实现专业班级姓名学号老师一课程设计的目的1通过具体的文件存储空间的管理文件的物理结构目录结构和文…
试验四文件系统一实验目的1用高级语言编写和调试一个简单的文件系统模拟文件管理的工作过程从而对各种文件操作命令的实质内容和执行过程有…
课程实验报告课程名称操作系统专业班级计算机科学与技术xxxx班学号xxxxxxx姓名xxxx指导老师xxxxx报告日期20xx年x…
操作系统上机实验报告班级学号姓名实验地点E区203实验时间20xx92620xx125实验一进程的建立实验目的创建进程及子进程在父…
昆明理工大学信息工程与自动化学院学生实验报告201201学年第二学期课程名称操作系统开课实验室年月日一实验目的用C或C语言编写和调…
Unix操作系统实验报告计算机科学与技术学院实验一Linux基本命令一实验目的掌握linux平台下的基本命令40个二实验说明在介绍…