操作系统实验文件系统(内含可运行代码)

一、实验内容

设计一个简单的二级文件系统。要求做到以下几点:

(1)可以实现下列几条命令(至少4条);

   login     用户登陆

   dir     列文件目录

   create 创建文件

   delete 删除文件

   open     打开文件

   close     关闭文件

   read     读文件

   write     写文件

(2)列目录时要列出文件名、物理地址、保护码和文件长度;

(3)源文件可以进行读写保护。

二、源码

#include<iostream>
#include<malloc.h>
#include<string.h>
using namespace std ;

 //定义文件数据结构
typedef struct file
{
    char file_name[20] ;
    bool file_protect[3] ;
    bool open_file_protect[3] ; //仅在文件打开时有效
    int  read , write ; //定义为读写指针
    int  file_length ;
    struct file *next ;
} File ;

//用户与文件的映射
typedef struct x_map
{
    char userName[20] ;
    File *file ;
    struct x_map *next ;
} Map ;

 //定义主文件目录
typedef struct mfd
{
    Map *head , *tail ;
} MFD ;

//打开文件目录
typedef struct afd
{
  File *head , *tail ;
  int max_open ;
  int current_open ;
} AFD ;

 //进行用户初始化登录
void login(MFD* mfd)
{
    //初始化两个不同用户
    for (int i = 1; i <= 2; i++)
    {
        Map* m;
        m = (Map*)malloc(sizeof(Map));
        if (m == NULL)
        {
            exit(0);
        }
        cout << "请初始化用户名 : ";
        cin >> m->userName;
        m->file = NULL;
        m->next = NULL;
        if (mfd->head == NULL)
        {
            mfd->head = mfd->tail = m;
        }
        else
        {
            mfd->tail->next = m;
            mfd->tail = m;
        }
    }
}

 //进行用户的查找,找到则返回用户映射指针
Map* quest(char userName[], MFD* mfd)
{
    Map* m = NULL;
    m = mfd->head;
    while (m)
    {
        if (strcmp(userName, m->userName) == 0)
        {
            return m;
        }
        m = m->next;
    }
    return NULL;
}

//进行文件的创建操作
bool create(Map* user, char file_name[], bool file_protect[3], int file_length)
{
    File* file;
    file = (File*)malloc(sizeof(File));
    if (file == NULL)
    {
        return false;
    }
    //进行文件的初始化
    strcpy_s(file->file_name, file_name);
    file->file_protect[0] = file_protect[0];
    file->file_protect[1] = file_protect[1];
    file->file_protect[2] = file_protect[2];
    file->file_length = file_length;
    file->read = file->write = 0;
    file->next = NULL;
    if (user->file == NULL)
    {
        user->file = file;
    }
    else
    {
        File* op;
        op = user->file;
    }
}

//进行文件删除操作
bool Delete(Map* user, char file_name[], AFD* afd)
{
    File* file = NULL, * prefile = NULL, * temp;
    file = afd->head;
    //在打开文件中查找
    while (file)
    {
        if (strcmp(file_name, file->file_name) == 0)
        {
            cout << "\"" << file_name << "\" 现在是打开状态 , 请先关闭 ! \n";
            return false;
        }
        file = file->next;
    }
    file = user->file;
    //在文件中进行查找
    while (file)
    {
        if (strcmp(file_name, file->file_name) == 0)
        {
            if (file == user->file)
            {
                temp = file;
                user->file = file->next;
            }
            else
            {
                temp = file;
                prefile->next = file->next;
            }
            delete temp;
            return true;
        }
        prefile = file;
        file = file->next;
    }
    if (prefile->next == NULL)
    {
        cout << "用户 " << user->userName << " 不存在文件 \"" << file_name << "\"" << endl;
    }
    return false;
}

//进行文件打开操作
bool open(Map* user, char file_name[], AFD* afd, bool open_file_protect[])
{
    File* file = NULL;
    file = user->file;
    while (file)
    {
        if (strcmp(file->file_name, file_name) == 0)
        {
            break;
        }
        file = file->next;
    }
    if (file)
    {
        File* xfile;
        xfile = (File*)malloc(sizeof(File));
        if (xfile == NULL)
        {
            return false;
        }
        *xfile = *file;
        //根据文件的权限进行打开权限的赋值
        if (xfile->file_protect[0] >= open_file_protect[0])
        {
            xfile->open_file_protect[0] = open_file_protect[0];
        }
        else
        {
            cout << "禁止读操作 !" << endl;
            return false;
        }
        if (xfile->file_protect[1] >= open_file_protect[1])
        {
            xfile->open_file_protect[1] = open_file_protect[1];
        }
        else
        {
            cout << "禁止写操作 ! " << endl;
            return false;
        }
        if (xfile->file_protect[2] >= open_file_protect[2])
        {
            xfile->open_file_protect[2] = open_file_protect[2];
        }
        else
        {
            cout << "禁止读写操作 ! " << endl;
            return false;
        }
        xfile->next = NULL;
        if (afd->head == NULL)
        {
            afd->head = afd->tail = xfile;
            afd->current_open += 1;
        }
        else if (afd->current_open < afd->max_open)
        {
            afd->tail->next = xfile;
            afd->tail = xfile;
            afd->current_open += 1;
        }
        else
        {
            cout << "打开的文件数量太多 ! " << endl;
            return false;
        }
    }
    else
    {
        cout << "文件 " << file_name << " 不存在 !" << endl;
        return false;
    }
}

//关闭文件
bool close(AFD* afd, char file_name[])
{
    File* file = NULL, * preFile = NULL, * temp = NULL;
    //在打开文件链表中进行查找
    file = afd->head;
    while (file)
    {
        if (strcmp(file->file_name, file_name) == 0)
        {
            if (file == afd->head)
            {
                if (file == afd->tail)
                {
                    temp = file;
                    afd->head = afd->tail = NULL;
                }
                else
                {
                    temp = file;
                    afd->head = file->next;
                }
            }
            else if (file == afd->tail)
            {
                temp = file;
                preFile->next = NULL;
                afd->tail = preFile;
            }
            else
            {
                temp = file;
                preFile->next = file->next;
            }
            delete temp;
            return true;
        }
        preFile = file;
        file = file->next;
    }
    cout << "文件不存在 ! " << endl;
    return false;
}

int main()
{
    MFD *mfd ;
    mfd = (MFD*)malloc(sizeof(MFD)) ;
    if(mfd == NULL)
    {
        exit(0) ;
    }
    mfd->head = mfd->tail = NULL ;
    login(mfd) ;
    char userName[20] ;
    while (true)
    {
        cout << "请选择用户登录 : ";
        cin >> userName;
        Map* user;
        user = quest(userName, mfd);
        if (user == NULL)
        {
            cout << "没有此用户! " << endl;
        }
        else
        {
            //为用户初始化打开文件目录
            AFD* afd;
            afd = (AFD*)malloc(sizeof(AFD));
            if (afd == NULL)
            {
                cout << "内存空间不足 ! " << endl;
                exit(0);
            }
            afd->head = afd->tail = NULL;
            afd->max_open = 5;
            afd->current_open = 0;
            char command[20];
            char file_name[20];
            bool file_protect[3];
            bool open_file_protect[3];
            int file_length;
            while (true)
            {
                cout << userName << ">>";
                cin >> command;
                //输入命令进行操作
                if (strcmp(command, "create") == 0)
                {
                    cout << "请输入你想创建的文件名 : ";
                    cin >> file_name >> file_protect[0] >> file_protect[1] >> file_protect[2] >> file_length;
                    create(user, file_name, file_protect, file_length);
                }
                else if (strcmp(command, "delete") == 0)
                {
                    cout << "请输入你想删除的文件名 : ";
                    cin >> file_name;
                    Delete(user, file_name, afd);
                }
                else if (strcmp(command, "open") == 0)
                {
                    cout << "请输入你想打开的文件名 : ";
                    cin >> file_name >> open_file_protect[0] >> open_file_protect[1] >> open_file_protect[2];
                    open(user, file_name, afd, open_file_protect);
                }
                else if (strcmp(command, "close") == 0)
                {
                    cout << "请输入你想关闭的文件名 : ";
                    cin >> file_name;
                    close(afd, file_name);
                }
                else if (strcmp(command, "exit") == 0)
                {
                    break;
                }
                else
                {
                    cout << "不存在此命令 \"" << command << "\"" << endl;
                }
            }
        }
    }
    return 0 ;
}

三、总体设计

此次我选择了 login用户登陆,create创建文件,delete删除文件,open打开文件,close关闭文件这五条指令进行实验。用户登录处可以进行多个用户的初始化及登录选择。

  1. 封装所需数据结构
  1. 定义文件数据结构

       一个文件需要包含文件名(file_name)作为标识作用,文件长度(file_length),文件保护位(file_protect譬如文件是只读文件、只写文件或是可读也可写文件,在读写操作中十分关键,决定了一个文件是否可以进行读写操作,虽然在我此次实验中不涉及读写操作,但为了其文件结构的完整性,依然选择添加。有了文件保护位,可以在进行读写指针(read, write)的设置,方便读写操作。最后在设置一个文件指针(next)以描述各文件之间的关系。

  1. 定义用户与文件的映射

       由于是多用户的文件系统,每一个用户都有自己拥有的文件,为了能够快速准确找到用户对于的文件,我们建立一个用户与文件的映射其中包含用户名(userName),文件(file),此时的文件是所属映射中的用户。而一个用户又可以拥有多个文件,所以再设置一个同类型的映射指针(next)用于一个用户与多文件映射之间进行联系。

  1. 定义主文件目录

       用户有多个文件,文件之间形成目录,创建好目录之后才能方便管理和显示。在结构体中设置头指针和尾指针(head, tail

  1. 定义打开文件目录

       由于删除文件仅能删除关闭的文件,处于打开状态的文件不可以删除。这是我们就需要文件打开目录来记录已打开的文件。但必须限制文件打开的数量,不能无限去打开文件。故设置一个最大打开数量(max_open),同样需要在结构体中设置头指针和尾指针(head, tail,因为有多个打开文件需要进行联系。

  1. login用户登陆

用户登录包括两个部分:初始化多个个不同用户进行用户的查找

  1. 初始化多个个不同用户login)

     使用 (Map*)malloc(sizeof(Map))动态开辟用户与文件的映射(即代表用户)

 开辟多个用户可以设置一个整型变量num用于记录用户个数,利用整型变量num控制循环次数,在每次循环中都为用户输入用户名。并建立用户之间的联系。

  1. 进行用户的查找quest

多用户管理系统要对用户登录时的用户进行校验,看是否存在此用户。用户存在用户与文件的映射m中。通过strcmp(userName, m->userName比对我们所输入用户名是否存在,利用循环进行多次判断,直至m为空仍没找到则返回flase。

  1. create创建文件

     先为文件的创建开辟空间,内存空间不足开辟失败,则直接返回flase。若成功开辟则继续执行,进行文件的初始化

使用strcpy_s(file->file_namefile_name)语句进行字符串拷贝对文件名进行初始化。最后建立文件与文件之间的联系。

  1. delete删除文件

删除文件之间先要进行额外的判断,判断文件是否处于打开状态。打开状态下的文件不可删除。在打开文件中通过循环遍历,使用strcmp(file_name, file->file_name) == 0语句判断在打开文件中是否存在。如果存在,则直接使用cout << "\"" << file_name << "\" 现在是打开状态 , 请先关闭 ! \n"语句输出文件是打开状态以提示用户并提前返回flase。若直至file为空仍未找到代表文件不存在或者处于关闭状态,可进入下一步判断。进入文件目录中以文件名作为索引寻找,若找到则改变指针关系,删除文件并返回ture。若直至文件目录为空还未找到则代表文件不存在。通过输出语句输出文件不存在以提示用户并返回flase。

  1. open打开文件

打开文件主要进行的就是将需要打开的文件链接到打开文件目录中。但在这之前需要进行至少两个判断,第一文件是否存在,第二文件是否已经处于打开状态。第一个判断与之前的判断文件是否存在一样,进入文件目录查找比对。如果文件不存在则通过输出语句输出文件不存在以提示用户并返回flase。如果文件存在则进行第二个判断,遍历文件打开目录,如果文件存在即已打开则返回ture,不进行链接到打开文件目录表中。如果文件不存在即未打开则将文件链接到打开文件目录表中并返回ture。

  1. close关闭文件

    关闭文件主要是将文件从文件打开目录中删除。同样其需要进行两个判断,第一文件是否存在,第二文件是否已经处于打开状态,因为只有打开状态下的文件才需关闭。第一个判断与之前的判断文件是否存在一样,进入文件目录查找比对。如果文件不存在则通过输出语句输出文件不存在以提示用户并返回flase。如果文件存在则进行第二个判断,遍历文件打开目录,如果文件存在即已打开则返回ture,改变指针关系将文件从文件打开目录中删除。如果文件不存在即文件是关闭状态不需要重复关闭直接并返回ture。

(注:文件删除是从文件目录中将文件删除,文件关闭是将文件从文件打开目录中将文件删除,文件起始还存在与文件目录中。)

四、测试及结果分析

  1. 为方便调试,多用户文件管理系统我们仅初始化两个用户
  2. 输入两个用户,c和d
  3. 选择用户e登录提示“没有此用户”
  4. 选择用户c登录,进入用户c进行如下操作。

第一步创建file0,file1,file2;

第二步打开file0,file1,file2,file7,file7不在文件目录中,故提示file7文件不存在;

第三步:关闭file1

第四步:删除file0,file1,file2,其中file0,而file2处于打开状态不得删除。

5、选择用户d登录,进入用户d进行操作,与用户c类似。

第一步创建dictory5,dictory6,dictory7;

第二步打开dictory5,dictory6,dictory7,dictory1,而dictory1不在文件目录中,故提示dictory1文件不存在;

第三步:关闭dictory6

第四步:删除dictory5,dictory6,dictory7,其中dictory5,dictory7,处于打开状态不得删除。

          

 

 

 

  • 12
    点赞
  • 106
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
#include <stdio.h> #include <memory.h> #include <string> #include <iostream> using namespace std; //1代表普通文件2代表目录文件0表示空文件 #define GENERAL 1 #define DIRECTORY 2 #define HXSH 0 struct FCB { char fname[16]; //文件名 char type; int size; //文件大小 int fatherBlockNum; //当前的父目录盘块号 int currentBlockNum; //当前的盘块 void initialize() { strcpy(fname,"\0"); type = HXSH; size =0; fatherBlockNum = currentBlockNum = 0; } }; /*常量设置*/ const char* FilePath = "C:\\myfiles"; const int BlockSize = 512; //盘块大小 const int OPEN_MAX = 5; //能打开最多的文件数 const int BlockCount = 128; //盘块数 const int DiskSize = BlockSize*BlockCount; //磁盘大小 const int BlockFcbCount = BlockSize/sizeof(FCB);//目录文件的最多FCB数 int OpenFileCount = 0; struct OPENLIST //用户文件打开表 { int files; //当前打开文件数 FCB f[OPEN_MAX]; //FCB拷贝 OPENLIST() { files=0; for(int i=0;i<OPEN_MAX;i++){ f[i].fatherBlockNum=-1;//为分配打开 f[i].type=GENERAL; } } }; /*-------------目录文件结构---------------*/ struct dirFile { struct FCB fcb[BlockFcbCount]; void init(int _FatherBlockNum,int _CurrentBlockNum,char *name)//父块号,当前块号,目录名 { strcpy(fcb[0].fname,name); //本身的FCB fcb[0].fatherBlockNum=_FatherBlockNum; fcb[0].currentBlockNum=_CurrentBlockNum; fcb[0].type=DIRECTORY; //标记目录文件 for(int i=1;i<BlockFcbCount;i++){ fcb[i].fatherBlockNum=_CurrentBlockNum; //标记为子项 fcb[i].type=HXSH; // 标记为空白项 } } }; /**********************************************************************/ struct DISK { int FAT1[BlockCount]; //FAT1 int FAT2[BlockCount]; //FAT2 struct dirFile root; //根目录 char data[BlockCount-3][BlockSize]; void format() { memset(FAT1,0,BlockCount); //FAT1 memset(FAT2,0,BlockCount); //FAT2 FAT1[0]=FAT1[1]=FAT1[2]=-2; //0,1,2盘块号依次代表FAT1,FAT2,根目录区 FAT2[0]=FAT2[1]=FAT2[2]=-2; //FAT作备份 root.init(2,2,"C:\\");//根目录区 memset(data,0,sizeof(data));//数据区 } }; /*-----------------全局变量--------------------------*/ FILE *fp; //磁盘文件地址 char * BaseAddr; //虚拟磁盘空间基地址 string currentPath="C:\\\\"; //当前路径 int current=2; //当前目录的盘块号 string cmd; //输入指令 struct DISK *osPoint; //磁盘操作系统指针 char command[16]; //文件名标识 struct OPENLIST* openlist; //用户文件列表指针 /*-----------函数事先申明--------------------*/ int format(); int mkdir(char *sonfname); int rmdir(char *sonfname); int create(char *name); int listshow(); int delfile(char *name); int changePath(char *sonfname); int write(char *name); int exit(); int open(char *file); int close(char *file); int read(char *file); /*------------初始化-----------------------*/ int format() { current = 2; currentPath="C:\\\\"; //当前路径 osPoint->format();//打开文件列表初始化 delete openlist; openlist=new OPENLIST; /*-------保存到磁盘上myfiles--------*/ fp = fopen(FilePath,"w+"); fwrite(BaseAddr,sizeof(char),DiskSize,fp); fclose(fp); printf("----------------------------------------------------------\n\n"); return 1; } /*-----------------------创建子目录-------------------*/ int mkdir(char *sonfname) { //判断是否有重名 //寻找空白子目录项 //寻找空白盘块号 //当前目录下增加该子目录项 //分配子目录盘块,并且初始化 //修改fat表 int i,temp,iFAT; struct dirFile *dir; //当前目录的指针 if(current==2) dir=&(osPoint->root); else dir=(struct dirFile *)(osPoint->data [current-3]); /*--------为了避免该目录下同名文件夹--------*/ for(i = 1;i<BlockFcbCount;i++) { if(dir->fcb[i].type==DIRECTORY && strcmp(dir->fcb[i].fname,sonfname)==0 ) { printf("该文件夹下已经有同名的文件夹存在了!\n"); return 0; } } //查找空白fcb序号 for(i=1;i<BlockFcbCount;i++) { if(dir->fcb[i].type==HXSH) break; } if(i==BlockFcbCount) { printf("该目录已满!请选择新的目录下创建!\n"); return 0; } temp=i; for(i = 3;i < BlockCount;i++) { if(osPoint->FAT1[i] == 0) break; } if(i == BlockCount) { printf("磁盘已满!\n"); return 0; } iFAT=i; /*-------------接下来进行分配----------*/ osPoint->FAT1[iFAT]=osPoint->FAT2[iFAT] = 2; //2表示分配给下级目录文件 //填写该分派新的盘块的参数 strcpy(dir->fcb[temp].fname,sonfname); dir->fcb[temp].type=DIRECTORY; dir->fcb[temp].fatherBlockNum=current; dir->fcb[temp].currentBlockNum=iFAT; //初始化子目录文件盘块 dir=(struct dirFile*)(osPoint->data [iFAT-3]); //定位到子目录盘块号 dir->init (current,iFAT,sonfname);//iFAT是要分配的块号,这里的current用来指要分配的块的父块号 printf("---------------------------------------------------------------\n\n"); return 1; } /*-------删除当前目录下的文件夹--------*/ int rmdir(char *sonfname) { int i,temp,j;//确保当前目录下有该文件,并记录下该FCB下标 struct dirFile *dir; //当前目录的指针 if(current==2) dir=&(osPoint->root); else dir=(struct dirFile *)(osPoint->data [current-3]); for(i=1;i<BlockFcbCount;i++) { //查找该目录文件 if(dir->fcb[i].type==DIRECTORY && strcmp(dir->fcb[i].fname,sonfname)==0) { break; } } temp=i; if(i==BlockFcbCount) { printf("当前目录下不存在该子目录!\n"); return 0; } j = dir->fcb[temp].currentBlockNum; struct dirFile *sonDir; //当前子目录的指针 sonDir=(struct dirFile *)(osPoint->data [ j - 3]); for(i=1;i<BlockFcbCount;i++) //查找子目录是否为空目录 { if(sonDir->fcb[i].type!=HXSH) { printf("该文件夹为非空文件夹,为确保安全,请清空后再删除!\n"); return 0; } } /*开始删除子目录操作*/ osPoint->FAT1[j] = osPoint->FAT2[j]=0; //fat清空 char *p=osPoint->data[j-3]; //格式化子目录 memset(p,0,BlockSize); dir->fcb[temp].initialize(); //回收子目录占据目录项 printf("---------------------------------------------------------------\n\n"); return 1; } /*-----------在当前目录下创建文本文件---------------*/ int create(char *name) { int i,iFAT;//temp, int emptyNum = 0,isFound = 0; //空闲目录项个数 struct dirFile *dir; //当前目录的指针 if(current==2) dir=&(osPoint->root); else dir=(struct dirFile *)(osPoint->data [current-3]); //查看目录是否已满 //为了避免同名的文本文件 for(i=1;i<BlockFcbCount;i++) { if(dir->fcb[i].type == HXSH && isFound == 0) { emptyNum = i; isFound = 1; } else if(dir->fcb[i].type==GENERAL && strcmp(dir->fcb[i].fname,name)==0 ) { printf("无法在同一目录下创建同名文件!\n"); return 0; } } if(emptyNum == 0) { printf("已经达到目录项容纳上限,无法创建新目录!\n"); return 0; } //查找FAT表寻找空白区,用来分配磁盘块号j for(i = 3;i<BlockCount;i++) { if(osPoint->FAT1[i]==0) break; } if(i==BlockCount) { printf("磁盘已满!\n"); return 0; } iFAT=i; /*------进入分配阶段---------*/ //分配磁盘块 osPoint->FAT1[iFAT] = osPoint->FAT2[iFAT] = 1; /*-----------接下来进行分配----------*/ //填写该分派新的盘块的参数 strcpy(dir->fcb[emptyNum].fname,name); dir->fcb[emptyNum].type=GENERAL; dir->fcb[emptyNum].fatherBlockNum=current; dir->fcb[emptyNum].currentBlockNum=iFAT; dir->fcb[emptyNum].size =0; char* p = osPoint->data[iFAT -3]; memset(p,4,BlockSize); printf("----------------------------------------------------------------\n\n"); return 1; } /*-------查询子目录------------*/ int listshow() { int i,DirCount=0,FileCount=0; //搜索当前目录 struct dirFile *dir; //当前目录的指针 if(current==2) dir=&(osPoint->root); else dir=(struct dirFile *)(osPoint->data [current-3]); for(i=1;i<BlockFcbCount;i++) { if(dir->fcb[i].type==GENERAL) { //查找普通文件 FileCount++; printf("%s 文本文件.\n",dir->fcb[i].fname); } if(dir->fcb[i].type==DIRECTORY) { //查找目录文件 DirCount++; printf("%s 文件夹.\n",dir->fcb[i].fname); } } printf("\n该目录下共有 %d 个文本文件, %d 个文件夹\n\n",FileCount,DirCount); printf("--------------------------------------------------------\n\n"); return 1; } /*---------在当前目录下删除文件-----------*/ int delfile(char *name) { int i,temp,j; //确保当前目录下有该文件,并且记录下它的FCB下标 struct dirFile *dir; //当前目录的指针 if(current==2) dir=&(osPoint->root); else dir=(struct dirFile *)(osPoint->data [current-3]); for(i=1;i<BlockFcbCount;i++) //查找该文件 { if(dir->fcb[i].type==GENERAL && strcmp(dir->fcb[i].fname,name)==0) { break; } } if(i==BlockFcbCount) { printf("当前目录下不存在该文件!\n"); return 0; } int k; for(k=0;k<OPEN_MAX;k++) { if((openlist->f [k].type = GENERAL)&& (strcmp(openlist->f [k].fname,name)==0)) { if(openlist->f[k].fatherBlockNum == current) { break; } else { printf("该文件未在当前目录下!\n"); return 0; } } } if(k!=OPEN_MAX) { close(name); } //从打开列表中删除 temp=i; /*开始删除文件操作*/ j = dir->fcb [temp].currentBlockNum ; //查找盘块号j osPoint->FAT1[j]=osPoint->FAT2[j]=0; //fat1,fat2表标记为空白 char *p=osPoint->data[j - 3]; memset(p,0,BlockSize); //清除原文本文件的内容 dir->fcb[temp].initialize(); //type=0; //标记该目录项为空文件 printf("------------------------------------------------------------\n\n"); return 1; } /*--------------进入当前目录下的子目录--------------*/ int changePath(char *sonfname) { struct dirFile *dir; //当前目录的指针 if(current==2) dir=&(osPoint->root); else dir=(struct dirFile *)(osPoint->data [current-3]); /*回到父目录*/ if(strcmp(sonfname,"..")==0) { if(current==2) { printf("你现已经在根目录下!\n"); return 0; } current = dir->fcb[0].fatherBlockNum ; currentPath = currentPath.substr(0,currentPath.size() - strlen(dir->fcb[0].fname )-1); return 1; } /*进入子目录*/ int i,temp; //确保当前目录下有该目录,并且记录下它的FCB下标 for(i = 1; i < BlockFcbCount; i++) { //查找该文件 if(dir->fcb[i].type==DIRECTORY && strcmp(dir->fcb[i].fname,sonfname)==0 ) { temp=i; break; } } if(i==BlockFcbCount) { printf("不存在该目录!\n"); return 0; } //修改当前文件信息 current=dir->fcb [temp].currentBlockNum ; currentPath = currentPath+dir->fcb [temp].fname +"\\"; printf("-------------------------------------------------------------\n\n"); return 1; } /*--------System exit---------------------*/ int exit() { //将所有文件都关闭 //保存到磁盘上C:\myfiles fp=fopen(FilePath,"w+"); fwrite(BaseAddr,sizeof(char),DiskSize,fp); fclose(fp); //释放内存上的虚拟磁盘 free(osPoint); //释放用户打开文件表 delete openlist; printf("---------------------------------------------------------\n\n"); return 1; } /*-------------在指定的文件里记录信息---------------*/ int write(char *name) { int i; char *startPoint,*endPoint; //在打开文件列表中查找 file(还需要考虑同名不同目录文件的情况!!!) for(i=0;i<OPEN_MAX;i++) { if(strcmp(openlist->f [i].fname,name)==0 ) { if(openlist->f[i].fatherBlockNum ==current) { break; } else { printf("该文件处于打开列表中,本系统只能改写当前目录下文件!\n"); return 0; } } } if(i==OPEN_MAX) { printf("该文件尚未打开,请先打开后写入信息!!\n"); return 0; } int active=i; int fileStartNum = openlist->f[active].currentBlockNum - 3 ; startPoint = osPoint->data[fileStartNum]; endPoint = osPoint->data[fileStartNum + 1]; printf("请输入文本以Ctrl D号结束:\t"); char input; while(((input=getchar())!=4)) { if(startPoint < endPoint-1) { *startPoint++ = input; } else { printf("达到单体文件最大容量!"); *startPoint++ = 4; break; } } return 1; } /*---------选择一个打开的文件读取信息----------*/ int read(char *file) { int i,fileStartNum; char *startPoint,*endPoint; //struct dirFile *dir; //在打开文件列表中查找 file(还需要考虑同名不同目录文件的情况!!!) for(i=0;i<OPEN_MAX;i++) { if(strcmp(openlist->f [i].fname,file)==0 ) { if(openlist->f[i].fatherBlockNum ==current) { break; } else { printf("该文件处于打开列表中,本系统只能阅读当前目录下文件!\n"); return 0; } } } if(i==OPEN_MAX) { printf("该文件尚未打开,请先打开后读取信息!\n"); return 0; } int active=i; //计算文件物理地址 fileStartNum = openlist->f[active].currentBlockNum - 3 ; startPoint = osPoint->data[fileStartNum]; endPoint = osPoint->data[fileStartNum + 1]; //end_dir=(struct dirFile *)[BlockSize-1]; //q=(char *)end_dir; printf("该文件的内容为: "); while((*startPoint)!=4&& (startPoint < endPoint)) { putchar(*startPoint++); } printf("\n"); return 1; } /*当前目录下添加一个打开文件*/ int open(char *file)//打开文件 { int i,FcbIndex; //确保没有打开过该文件 = 相同名字 + 相同目录 for(i=0;i<OPEN_MAX;i++) { if(openlist->f[i].type ==GENERAL && strcmp(openlist->f [i].fname,file)==0 &&openlist;->f[i].fatherBlockNum == current) { printf("该文件已经被打开!\n"); return 0; } } //确保有空的打开文件项 if(openlist->files == OPEN_MAX) { printf("打开文件数目达到上限!无法再打开新文件.\n"); return 0; } //确保当前目录下有该文件,并且记录下它的FCB下标 struct dirFile *dir; //当前目录的指针 if(current==2) dir=&(osPoint->root); else dir=(struct dirFile *)(osPoint->data [current-3]); for(i = 1;i< BlockFcbCount;i++) { //查找该文件 if(dir->fcb[i].type==GENERAL && strcmp(dir->fcb[i].fname,file)==0 ) { FcbIndex=i; break; } } if(i==BlockFcbCount) { printf("当前目录下不存在该文件!\n"); return 0; } //装载新文件进入打开文件列表,(FCB信息,文件数++) ??难道名字过不来? openlist->f[OpenFileCount] = dir->fcb[FcbIndex]; //FCB拷贝 openlist->files ++; printf("文件打开成功!\n"); OpenFileCount++; return 1; } int close(char *file) { //释放该文件所占内存 //释放用户打开文件列表表项 int i; //在打开文件列表中查找 file(还需要考虑同名不同目录文件的情况!!!) for(i=0;i<OPEN_MAX;i++) { if((openlist->f [i].type = GENERAL)&& (strcmp(openlist->f [i].fname,file)==0)) { if(openlist->f[i].fatherBlockNum == current) { break; } else { printf("该文件已打开,但未在当前目录下,无法关闭!\n"); return 0; } } } if(i==OPEN_MAX) { printf("该文件未在打开列表中!\n"); return 0; } int active=i; openlist->files --; openlist->f[active].initialize(); OpenFileCount--; printf("该文件已关闭!\n"); return 1; } int main() { /*********************************************************************/ printf("-----Welcome To My Operate System Of File(FAT)-----\n"); //使用说明书 printf("\n 以下是使用说明书:\n"); printf("--------------------------------------------------------------\n"); printf("|| format :对磁盘格式化. || \n"); printf("|| exit :安全退出该文件系统,保存信息. || \n"); printf("|| mkdir dirname :创建子目录. || \n"); printf("|| rmdir dirname :删除子目录. || \n"); printf("|| ls dirname :显示当前目录下信息. || \n"); printf("|| cd dirname :更改当前目录. || \n"); printf("|| create filename :创建一个新文件,并且打开. || \n"); printf("|| write filename :选择一个打开的文件写入信息 || \n"); printf("|| read filename :选择一个打开的文件读取信息. || \n"); printf("|| rm filename :删除文件. || \n"); printf("|| open filename :打开文件. || \n"); printf("|| close filename :关闭文件. || \n"); printf("-------------------------------------------------------------\n\n"); //创建用户文件打开表 openlist=new OPENLIST; //申请虚拟空间并且初始化 BaseAddr=(char *)malloc(DiskSize); //虚拟磁盘初始化 osPoint=(struct DISK *)(BaseAddr); //加载磁盘文件 if((fp=fopen(FilePath,"r"))!=NULL){ fread(BaseAddr,sizeof(char),DiskSize,fp); printf("加载磁盘文件( %s )成功,现在可以进行操作了!\n\n",FilePath); } else{ printf("这是你第一次使用该文件管理系统!\t正在初始化...\n"); format(); printf("初始化已经完成,现在可以进行操作了!\n\n"); } printf("--------------------------------------------------------------\n\n"); while(1){ cout<<currentPath; cin>>cmd; if(cmd=="format"){ format(); } else if(cmd=="mkdir"){ cin>>command; mkdir(command); } else if(cmd=="rmdir"){ cin>>command; rmdir(command); } else if(cmd=="ls"){ listshow(); } else if(cmd=="cd"){ cin>>command; changePath(command); } else if(cmd=="create"){ cin>>command; create(command); } else if(cmd=="write"){ cin>>command; write(command); } else if(cmd=="read"){ cin>>command; read(command); } else if(cmd=="rm"){ cin>>command; delfile(command); } else if(cmd=="open"){ cin>>command; open(command); } else if(cmd=="close"){ cin>>command; close(command); } else if(cmd=="exit"){ exit(); break; } else cout<<"无效指令,请重新输入:"<<endl; } printf("Thank you for using my file system!\n"); return 0; }
西安工业大学计算机操作系统实验中,解析ELF文件是一个重要的任务。ELF(Executable and Linkable Format,可执行与可链接格式)是一种通用的二进制文件格式,用于存储可执行程序、共享库和目标文件的相应信息和数据。 解析ELF文件的目的是了解文件的结构、各个部分的功能和含义,以便能够正确加载和执行程序。具体而言,解析ELF文件包括以下几个方面的内容: 1. ELF头部解析:ELF文件以一个固定的头部开始,其中包含了文件类型、目标体系结构、入口地址等基本信息。通过解析ELF头部,可以获取这些重要的文件属性,从而对文件进行正确的解析和处理。 2. 程序头表解析:ELF文件的程序头表记录了可执行文件在虚拟内存中的各个段的信息,如代码段、数据段、BSS段等。通过解析程序头表,可以获取程序的加载和运行所需的内存布局信息,便于操作系统正确加载和映射这些段到内存中。 3. 节头表解析:ELF文件的节头表记录了各个节(section)的信息,包括各个节的起始地址、大小、类型和属性等。常见的节有代码节、数据节、符号表等。通过解析节头表,可以获取各个节的具体信息,便于操作系统进行链接、重定位和符号解析等操作。 4. 符号表解析:ELF文件的符号表记录了程序中定义和引用的符号(如函数名、变量名)以及它们的地址和类型等信息。通过解析符号表,可以实现符号的动态链接和重定位等功能,确保程序能正确地运行。 通过对ELF文件的解析,操作系统可以准确理解和处理可执行程序中的各个组成部分,为程序的加载和执行提供必要的支持。同时,对ELF文件的解析也为进程间的通信和共享提供了基础,实现了程序的模块化和可复用性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老斧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值