[操做系統][簡單文件系統實現]

簡單文件系統的實現

要求

  • 內存中開闢一塊虛擬磁盤空間做爲文件存儲分區,在其上實現一個簡單的基於多級目錄單用戶單任務系統中的文件系統。ios

  • 在退出該文件系統的使用時,虛擬文件系統以一個文件的方式保存到磁盤中,以便下次能夠把它恢復到內存的虛擬存儲空間git

實際實現

  • 以上兩點均實現
  • 能處理絕對路徑和相對路徑的命令
    • 例如 :
      • cd /home/zy/Desktop/ 這樣的絕對路徑
      • cd ../hah/1/2 這樣的相對路徑
    • mkdir,rmdir,cd,creat,rm均支持
    • open_pathopen的升級版,也是支持上述函數實現的主要函數。
  • 包裝open,read,close實現了一個cat直接打印文件內容。
    • 檢查文件是否打開,若是打開了直接進行下一步,沒有就打開
    • read出全部內容
    • 若是以前不是打開的那麼就關閉文件。

截圖

  • 創建目錄樹,/home是用戶的根目錄github

    /home下有/zy函數

    /zy下有 /Documents,/Desktop,/Viedeos,Music測試

  • /home/zy/Documents目錄下創建一個文件Hello.txt
    • 並輸入內容Hello World!Fisrt,能正確顯示長度和文件內容。
    • 測試了creat,open,closeread,write等基本用法

  • 利用creat /home/zy/hellozy.txt/home/zy下創建了一個hellozy.txt
    • 測試了creat路徑下的用法

  • 測試了mkdir,cd,rmdir在路徑下也能正常工做。其他幾個相似的同理,OVERspa

能夠改進的地方

  • 有一些BUG還待處理
  • 完善異常處理機制
  • 完善文件信息,包括建立時間,修改時間。
  • 嘗試實現多任務的文件系統。

如下代碼並不是最終版本,以後還略有修改,詳細代碼存放在github

OS.h

幾個常量定義

#include <cstdio>
#include <memory.h>
#include <string>
#include <iostream>
#include <malloc.h>
#include <time.h>
using namespace std;
/*常量定義*/
#define  Path  "/home" //根目錄
#define BLOCKSIZE  1024 //磁盤塊大小
#define BLOCKCOUNT  1000 //盤塊大小
#define MAXOPENFILE 10       //能打開最多的文件數
#define DISKSIZE  (BLOCKSIZE*BLOCKCOUNT)//磁盤大小
#define END -1
const int FCBCOUNT = BLOCKSIZE/sizeof(FCB);//一個塊的最多FCB數量

DISK,DirFile,USEROPEN,FCB定義

DISK定義

  • 總共1000個磁盤塊
    • FAT1:4個
    • FAT2:4個
    • 根目錄 1個
    • 其他數據 991個

代碼:命令行

/*------------------磁盤------------------------*/
struct DISK
{
    int FAT1[BLOCKCOUNT];//磁盤塊0-3表明FAT
    int FAT2[BLOCKCOUNT];//磁盤塊4-7表明FAT2
    DirFile RootDir;    //根目錄 磁盤塊8
    char Data[BLOCKCOUNT-9][BLOCKSIZE];//目錄和其餘文件 磁盤塊9~1000
};

DirFile 定義

代碼:指針

/*-----------------目錄文件---------------------*/
struct DirFile{
    FCB fcb[FCBCOUNT];  //文件控制塊
    void init(int father,int self)
    {
        //給根目錄建立.. 和 .  序號0放".", 序號1放".."
        memset(fcb,0,sizeof(fcb));
        fcb[1].free=fcb[0].free=1;
        fcb[1].attribute=fcb[0].attribute=1;
        fcb[1].first=father;
        fcb[0].first=self;
        memcpy(fcb[0].filename,".",sizeof("."));
        memcpy(fcb[1].filename,"..",sizeof(".."));
    }
};

FCB

struct FCB
{
    char filename[12]; //文件名
    char attribute;//0表示目錄,1表示數據文件
    int time;//建立時間
    int data;//建立日期
    int first;//起始盤號
    int length;//長度
    char free;//表示目錄項是否爲空
};

USEROPEN

struct USEROPEN
{
    FCB fcb;
    char dir[80];//相應打開文件所在的目錄名
    int count;//讀寫指針在文件的位置
    char fcbstate;//是否修改了文件的FCB內容,修改了置爲1,不然置爲0
    char topenfile;//表示該用戶表項是否被佔用,1就是被佔用,0就是沒有被佔用
    char fatherfilename[12];//上一層目錄的名字
    int pos;
};

main.cpp

解析

  • 全局變量的聲明
  • 簡單的處理命令行的讀入。
  • ls函數

代碼

#include "OS.h"
using namespace std;

/*-------------函數聲明------------------------*/
void help();

int cd(char *dirname);

int startsys();

int format();

int mkdir(char *dirname);

int rmdir(char *dirname);

int close(int fd);

int open(char *filename);

int creat(char *filename);

int rm(char *filename);

int filewrite(int fd);

int dowrite(int fd,char *text,int len, char wstyle);

int fileread(int fd,int len);

int doread(int fd,int len,char *text);

void exitsys();
/*--------------全局變量-------------------------*/
char* myvhard;//虛擬磁盤起始地址
string currentdir="/home";//當前目錄
string cmd; //讀取指令
USEROPEN openfilelist[MAXOPENFILE];//文件打開表
USEROPEN *ptrcuridr;//當前目錄在文件打開表的位置
DISK* disk;//將內容結構化
char command[50];//文件名標示符




/*--------------------- 顯示目錄函數 ---------------*/
void ls() {
    int BlockDirNum = (ptrcuridr->fcb).first;
    DirFile *dir = (DirFile *) disk->Data[BlockDirNum - 8];
    for (int i = 0; i < FCBCOUNT; i++) {
        if (dir->fcb[i].free == 1) {
            if (dir->fcb[i].attribute == 0)
                printf("%10s---length:%5d----File\n",dir->fcb[i].filename,dir->fcb[i].length);
            else
                printf("%10s---length:%5d----Directory\n",dir->fcb[i].filename,dir->fcb[i].length);
        }
    }
}



int main() {
    printf("Welcome the OS FileSystem\n");
    printf("input 'help' get more information\n\n\n");
   // freopen("E:\\OSFileSystem\\a.in","r",stdin);
    startsys(); //Init the System
    int len;
    while(1)
    {
        cout<<currentdir+">";
        cin>>cmd;
        if(cmd=="help"){            //幫助
            help();
        }
        else if(cmd=="mkdir"){
            cin>>command;
            mkdir(command);
        }
        else if(cmd=="cd"){
            cin>>command;
            cd(command);
        }
        else if(cmd=="exit") {
            break;
        }
        else if(cmd=="rmdir"){
            cin>>command;
            rmdir(command);
        }
        else if(cmd=="ls"){
            ls();
        }
        else if(cmd=="open"){
            cin>>command;
            open(command);
        }
        else if(cmd=="close"){
            cin>>command;
            close(atoi(command));
        }
        else if(cmd=="creat"){
            cin>>command;
            creat(command);
        }
        else if(cmd=="rm"){
            cin>>command;
            rm(command);
        }
            //
        else if(cmd=="write"){
            cin>>command;
            filewrite(atoi(command));
        }
        else if(cmd=="read") {
            cin >> command >> len;
            fileread(atoi(command),len);
        }
        else if(cmd=="exitsys"){
            exitsys();
        }else {
            printf("The cmd is not exits\n");
        }
    }
}

startsys.cpp

分析

  • int format()
    • 分配磁盤空間
    • 初始化根目錄
      • 加入...兩個子目錄
  • int startsys()
    • 申請磁盤空間
    • 載入以前的磁盤,若是沒有就申請。
    • 把根目錄加載進文件打開表。code

      代碼

    #include "OS.h"
    /--------------全局變量-------------------------/
    extern char* myvhard;//虛擬磁盤起始地址
    extern string currentdir;//當前目錄
    extern string cmd; //讀取指令
    extern USEROPEN openfilelist[MAXOPENFILE];//文件打開表
    extern USEROPEN ptrcuridr;//當前目錄在文件打開表的位置
    extern DISK
    disk;//將內容結構化
    extern char command[50];//文件名標示符
    /--------------------------------磁盤格式化函數-------------------/
    int format() {
    memset(myvhard,0,DISKSIZE);
    //建立根目錄,在磁盤塊8orm

    //前九個被FAT1+FAT2+root佔用
      for(int i=0;i<9;i++){
          disk->FAT1[i]=disk->FAT2[i]=-2;//-2表明被佔用
      }
      DirFile *dir=(DirFile *)disk->Data[8-8];//注意Data和FAT的區別
      //初始化根目錄.
      dir->init(8,8);
      return 1;

    }

    /--------------------------------進入文件系統函數--------------------/
    int startsys() {
    myvhard=(char )malloc(DISKSIZE); //申請10241000磁盤空間
    disk=(DISK )myvhard;
    FILE
    fp=fopen("myfsys","r");
    if(fp!=NULL)
    {
    printf("|-------------------------------------------|\n");
    printf("|-----------myfsys is loading---------------|\n");
    printf("|-------------------------------------------|\n\n");
    fread(myvhard,sizeof(char),DISKSIZE,fp);
    fclose(fp);
    }
    else{
    printf("|-------------------------------------------|\n");
    printf("|-----------myfsys is not exit--------------|\n");
    printf("|--File system is being created now --------|\n");
    printf("|-------------------------------------------|\n\n");
    format();
    }
    //初始化用戶打開表
    memset(openfilelist,0,sizeof(openfilelist));
    //將根目錄打開,首先修改fcb裏的內容
    openfilelist->fcb.first=8;
    //文件打開表項的內容
    openfilelist[0].topenfile=1;
    strcpy(openfilelist->dir,"");
    strcpy(openfilelist->fcb.filename,"home");
    strcpy(openfilelist->fatherfilename,"");
    ptrcuridr=&openfilelist[0];
    openfilelist[0].pos=0;
    //當前目錄設置爲根目錄
    currentdir=Path;
    return 1;
    }

OPEN.CPP

分析

  • 處理好...兩個子目錄

  • 維護好openfilelist裏的每一個值

    代碼

    #include "OS.h"

    /--------------全局變量-------------------------/
    extern char* myvhard;//虛擬磁盤起始地址
    extern string currentdir;//當前目錄
    extern string cmd; //讀取指令
    extern USEROPEN openfilelist[MAXOPENFILE];//文件打開表
    extern USEROPEN ptrcuridr;//當前目錄在文件打開表的位置
    extern DISK
    disk;//將內容結構化
    extern char command[50];//文件名標示符

    /-----------------------------打開文件函數--------------------/
    int open(char *filename){

    //檢查要被打開文件是否存在
      int BlockDirNum = (ptrcuridr->fcb).first;
      DirFile *dir = (DirFile *) disk->Data[BlockDirNum - 8];
      int Fileaddr = -1;
      for (int i = 0; i < FCBCOUNT; i++) {
          if (dir->fcb[i].free == 1 && strcmp(dir->fcb[i].filename, filename) == 0)//表項被使用,且是目錄,且文件名相等
          {
              Fileaddr = i;//文件存在
              break;
          }
      }
      //文件不存在 輸出-1
      if(Fileaddr==-1){
          printf("file does not exist\n");
          return -1;
      }
    
      //檢查打開文件表是否還有空表項,沒有報錯,有則記錄
      int OpenFileaddr=-1;
      for(int i=0;i<MAXOPENFILE;i++) {
          if (openfilelist[i].topenfile == 0) {
              OpenFileaddr=i;
          }
      }
      //沒有空表了
      if(OpenFileaddr==-1) {
          printf("File open table is full \n");
          return -1;
      }
      //若是又要打開一個根目錄,那麼直接返回0
      if(dir->fcb[Fileaddr].first==8)
      {
          OpenFileaddr=0;
          if(ptrcuridr->fcb.first==8)
              return 0;
      }
      //爲該文件填寫文件打開表項
    
      //檢查是否已經打開
      //須要一個temp來表示實際的dir值
      char temp[300];
      if(strcmp(filename,"..")==0)
      {
          strcpy(temp,ptrcuridr->dir);
          int len1=strlen(ptrcuridr->dir);
          int len2=strlen(ptrcuridr->fatherfilename);
          temp[len1-len2-1]=0;
      }
      else
      {
          char buffer[80];
          memset(buffer,0,sizeof(buffer));
          strcat(strcat(strcat(buffer,ptrcuridr->dir),"/"),ptrcuridr->fcb.filename);
          strcpy(temp,buffer);
      }
      for(int i=1;i<MAXOPENFILE;i++) {
          //"."必定是被打開了
          if ((openfilelist[i].topenfile == 1 && strcmp(openfilelist[i].fcb.filename, filename) == 0 &&
               strcmp(openfilelist[i].dir,temp) ==0 )||(strcmp(filename,".")==0))
               {
              printf(" The file has been opened !\n");
              return -1;//無效返回-1
          }
      }
      if(strcmp(filename,"..")==0)
      {
          openfilelist[OpenFileaddr].fcb=dir->fcb[Fileaddr];
          //名字是錯的,會是"..";正確的名字在工做塊的父親名字
          strcpy(openfilelist[OpenFileaddr].fcb.filename,ptrcuridr->fatherfilename);
          //曾經的路徑減去名字減去'/' 就是新的
          strcpy(openfilelist[OpenFileaddr].dir,ptrcuridr->dir);
          int len1=strlen(openfilelist[OpenFileaddr].dir);
          int len2=strlen(ptrcuridr->fatherfilename);
          openfilelist[OpenFileaddr].dir[len1-len2-1]=0;
          //找新的fathername,經過分析dir來獲得
          char test[20];
          strcpy(test,openfilelist[OpenFileaddr].dir);
          char *q;
          int len=strlen(test);
          for(int i=0;i<len;i++)
          {
              if(test[i]=='/'&&i!=len-1)
                  q=test+i+1;
          }
          strcpy(openfilelist[OpenFileaddr].fatherfilename,q);
      }
      else
      {
          openfilelist[OpenFileaddr].fcb=dir->fcb[Fileaddr];
          char buffer[80];
          memset(buffer,0,sizeof(buffer));
          strcat(strcat(strcat(buffer,ptrcuridr->dir),"/"),ptrcuridr->fcb.filename);
          strcpy(openfilelist[OpenFileaddr].dir,buffer);
          strcpy(openfilelist[OpenFileaddr].fatherfilename,ptrcuridr->fcb.filename);
      }
      openfilelist[OpenFileaddr].pos=OpenFileaddr;
      openfilelist[OpenFileaddr].count=0;
      openfilelist[OpenFileaddr].fcbstate=0;
      openfilelist[OpenFileaddr].topenfile=1;
      //返回文件描述符fd,此時的fd跟下標相同,通常不一樣.
      if(openfilelist[OpenFileaddr].fcb.attribute==0)//若是是文件,輸出文件打開符號
          printf("File Open Success,The fd is %d\n",OpenFileaddr);
      return OpenFileaddr;

    }

OPEN_PATH.CPP

分析

  • 讓系統函數都能處理絕對路徑相對路徑,而不單單是當前目錄下的文件了。
    • cd,mkdir,creaet,rm,rmdir
  • 使用的方式是拆分路徑的元素,而後分析元素

    不斷的調用openclose來實現。

代碼

#include "OS.h"
int open(char *filename);
int close(int fd);
/*--------------全局變量-------------------------*/
extern char* myvhard;//虛擬磁盤起始地址
extern string currentdir;//當前目錄
extern string cmd; //讀取指令
extern USEROPEN openfilelist[MAXOPENFILE];//文件打開表
extern USEROPEN *ptrcuridr;//當前目錄在文件打開表的位置
extern DISK* disk;//將內容結構化
extern char command[50];//文件名標示符

/*----------------------更改當前目錄函數---------------------

讀入一條文件路徑,返回一個打開的fd

 支持絕對路徑和相對路徑.

 輸出,若是路徑正確,返回文件打開後的fd.

------------------------------------------------------*/
int open_path(char *dirname) {
    //若是dirname是絕對路徑
    int fd=0, ok = 1, fdtemp = -1;//ok表明是否找到dirname所指的文件,fdtemp存臨時的,用來關閉
    USEROPEN *temp = ptrcuridr;//暫時保管一下ptrcuridr原始值,可能要回溯

    if (dirname[0] == '/') {
        ptrcuridr = openfilelist;//咱們的openfilelist[0]永遠是根目錄
        //使工做目錄暫時指向根目錄
        char *p = strtok(dirname + 1, "/");//用「/」分割 dirname[1]開始的字符串
        if (p != NULL) p = strtok(NULL, "/");//跳過/home
        while (p) {
            fd = open(p);
            if (fd == -1) {
                ok = 0;
                if (fdtemp != -1)  //離開前記得關文件
                    close(fdtemp);//把上個打開的文件關掉
                break;
            }
            ptrcuridr = openfilelist + fd;
            if (fdtemp != -1)
                close(fdtemp);//把上個打開的文件關掉
            fdtemp = fd;
            p = strtok(NULL, "/");
        }
    }
        //若是是相對路徑
    else {
        int len=strlen(dirname);
        dirname[len]='/';
        dirname[len+1]=0;
        char *p = strtok(dirname, "/");//用「/」分割 dirname[1]開始的字符串
        while (p) {
            fd = open(p);
            if (fd == -1) {
                ok = 0;
                if (fdtemp != -1)  //離開前記得關文件
                    close(fdtemp);//把上個打開的文件關掉
                break;
            }
            ptrcuridr = openfilelist + fd;
            if (fdtemp != -1)
                close(fdtemp);//把上個打開的文件關掉
            fdtemp = fd;
            p = strtok(NULL, "/");
        }
    }
         ptrcuridr = temp;
        //輸出數據
        if (ok == 1)
            return fd;
        else
            return -1;

}

close.cpp

分析

  • 記得把文件打開表的東西保存

代碼

#include "OS.h"
int open_path(char* dirname);
/*--------------全局變量-------------------------*/
extern char* myvhard;//虛擬磁盤起始地址
extern string currentdir;//當前目錄
extern string cmd; //讀取指令
extern USEROPEN openfilelist[MAXOPENFILE];//文件打開表
extern USEROPEN *ptrcuridr;//當前目錄在文件打開表的位置
extern DISK* disk;//將內容結構化
extern char command[16];//文件名標示符

/*---------------關閉文件函數-----------------*/
int close(int fd){
    //檢查fd的合法性
    if(fd>=MAXOPENFILE||fd<=0){
        printf(" Is not a legitimate fd \n");
        return -1;
    }else if(openfilelist[fd].topenfile==0){
        printf("filewrite ERROR:The File Don't Open\n");
        return -1;
    }

    //檢查用戶打開文件表表項的`fcbstate`字段,若是是1,則須要將該文件的FCB的內容保存的虛擬磁盤上該文件的目錄項
    //方法是:打開該文件的父目錄文件,已覆蓋寫方式調用do_wirte()將欲關閉的FCB寫入父目錄文件的相應盤塊.
    if(openfilelist[fd].fcbstate==1){
        char buffer[30]="..";
         int fatherfd=open_path(buffer);
        if(fatherfd!=-1) {
            //找到相應的盤號
            int pan1 = openfilelist[fatherfd].fcb.first;
            int area1 = -1;
            //盤號上相應的位置
            DirFile *dirson = (DirFile *) (disk->Data[pan1 - 8]);
            for (int i = 0; i < FCBCOUNT; i++) {
                if (dirson->fcb[i].free == 1  &&
                    strcmp(dirson->fcb[i].filename, openfilelist[fd].fcb.filename) == 0) {
                    //找到了該文件,覆蓋fcb
                    dirson->fcb[i] = openfilelist[fd].fcb;
                    break;
                }
            }
            //關文件
            if(fatherfd!=0)
            close(fatherfd);
        }
    }
    //回收該文件佔據的用戶打開表表項(clear),topenfile字段置0
    memset(openfilelist+fd,0,sizeof(openfilelist[0]));
    openfilelist[fd].topenfile=0;
    //返回
    return 0;
}

mkdir.cpp

分析

  • 利用open_path來返打開一個父級目錄,並返回fd
  • 將當前工做目錄ptrcuridr的原始值保存下來,而後將其賦值給那個父級目錄。
  • 最後還原ptrcuridr

代碼

#include "OS.h"
int close(int fd);
int open_path(char *dirname);
int FileSubstr(char *str);
/*--------------全局變量-------------------------*/
extern char* myvhard;//虛擬磁盤起始地址
extern string currentdir;//當前目錄
extern string cmd; //讀取指令
extern USEROPEN openfilelist[MAXOPENFILE];//文件打開表
extern USEROPEN *ptrcuridr;//當前目錄在文件打開表的位置
extern DISK* disk;//將內容結構化
extern char command[50];//文件名標示符




int mkdir(char *dirname)
{
    char newdir[20];
    char dirpath[60];
    USEROPEN *tempp = ptrcuridr;//暫時保管一下ptrcuridr原始值,可能要回溯
    int k=FileSubstr(dirname),fd=-1;
    if(k!=-1) {
        dirname[k] = 0;
        memset(newdir, 0, sizeof(newdir));
        memset(dirpath, 0, sizeof(dirpath));
        strcpy(newdir, dirname + k + 1);
        strcpy(dirpath, dirname);
        fd = open_path(dirpath);
        if(fd!=-1) {
            ptrcuridr = openfilelist + fd;
            dirname = newdir;
        }
        else {
            printf("error\n");
            return -1;
        }
        }


    //-------------如下爲一天前的代碼-----------------------//
    //讀取當前目錄的地址
    int BlockDirNum=(ptrcuridr->fcb).first;
    DirFile *dir=(DirFile *)disk->Data[BlockDirNum-8];
    //遍歷文件目錄,檢查是否有文件名相同的文件或目錄,並找一個沒有被使用的目錄空閒表項
    int temp=-1, DirFreeItems =-1;
    for(int i=0;i<FCBCOUNT;i++) {
        if (dir->fcb[i].free == 1 && strcmp(dir->fcb[i].filename, dirname) == 0)//表項被使用,且是目錄,且文件名相等
        {
            temp = i;//重名的表項
            break;
        }
        else if (dir->fcb[i].free == 0) {
            DirFreeItems = i;//目錄空閒表項
        }
    }
    //若是文件名已存在,報錯並退出
    if(temp!=-1)
    {
        printf("mkdir: cannot create directory '%s': Directory exists\n",dirname);
        if(fd!=-1)
            close(fd);
        ptrcuridr=tempp;
        return 0;
    }
    //若是沒有空閒位置,報錯退出
    if(DirFreeItems==-1)
    {
        printf("mkdir: cannot create directory '%s': Directory is full \n",dirname);
        if(fd!=-1)
            close(fd);
        ptrcuridr=tempp;
        return 0;
    }
    //檢查FAT中是否有空閒的盤塊
    int FATFreeItems=-1;
    for(int i = 0;i < BLOCKCOUNT;i++)
    {
        if(disk->FAT1[i] == 0) {//沒被使用的塊標記爲0
            FATFreeItems=i;//找到了一個空閒塊
            break;
        }
    }
    //若是FAT沒有空閒塊,報錯退出
    if(FATFreeItems==-1)
    {
        printf("mkdir: cannot create directory '%s': Disk is full \n",dirname);
        if(fd!=-1)
            close(fd);
        ptrcuridr=tempp;
        return 0;
    }
    /*----------------開始新建目錄-------------------*/
    //修改長度,fcbstate置爲1
    ptrcuridr->fcbstate=1;
    ptrcuridr->fcb.length++;//不包括.和..的
    //分配FAT的空閒塊,2表示被目錄使用
    disk->FAT1[FATFreeItems]=disk->FAT2[FATFreeItems]=2;
    //將改塊分配到 當前目錄的空閒項目下
    strcpy(dir->fcb[DirFreeItems].filename,dirname);
    dir->fcb[DirFreeItems].free=1;//被使用
    dir->fcb[DirFreeItems].attribute=1;//是目錄
    dir->fcb[DirFreeItems].first=FATFreeItems;//分配FAT空閒塊
    dir->fcb[DirFreeItems].length=0;
    dir->fcb[DirFreeItems].data=0;//時間以後弄
    dir->fcb[DirFreeItems].time=0;//時間以後弄
    //進入下一次目錄,初始化新得到的塊(重置給予"."和"..")
    dir=(DirFile*)(disk->Data[FATFreeItems-8]);
    dir->init(BlockDirNum,FATFreeItems);
    /*----------------恢復現場------------------------*/
    if(fd!=-1)
      close(fd);
    ptrcuridr=tempp;
    return 1;
}

rmdir.cpp

分析

  • mkdir相似

代碼

#include "OS.h"
int close(int fd);
int open_path(char *dirname);
int FileSubstr(char *str);
/*--------------全局變量-------------------------*/
extern char* myvhard;//虛擬磁盤起始地址
extern string currentdir;//當前目錄
extern string cmd; //讀取指令
extern USEROPEN openfilelist[MAXOPENFILE];//文件打開表
extern USEROPEN *ptrcuridr;//當前目錄在文件打開表的位置
extern DISK* disk;//將內容結構化
extern char command[50];//文件名標示符
/*-------------------------------刪除子目錄函數---------------------*/
int rmdir(char *dirname) {

    char newdir[20];
    char dirpath[60];
    USEROPEN *tempp = ptrcuridr;//暫時保管一下ptrcuridr原始值,可能要回溯
    int k=FileSubstr(dirname),fd=-1;
    if(k!=-1) {
        dirname[k] = 0;
        memset(newdir, 0, sizeof(newdir));
        memset(dirpath, 0, sizeof(dirpath));
        strcpy(newdir, dirname + k + 1);
        strcpy(dirpath, dirname);
        fd = open_path(dirpath);
        if(fd!=-1) {
            ptrcuridr = openfilelist + fd;
            dirname = newdir;
        }
        else {
            printf("error\n");
            return -1;
        }
    }



    /*---------使用open_path更新----------------------*/
    //檢查文件是否存在
    int BlockDirNum = (ptrcuridr->fcb).first;
    DirFile *dir = (DirFile *) disk->Data[BlockDirNum - 8];
    int temp = -1;
    for (int i = 0; i < FCBCOUNT; i++) {
        if (dir->fcb[i].free == 1 && dir->fcb[i].attribute == 1 &&
            strcmp(dir->fcb[i].filename, dirname) == 0)//表項被使用,且是目錄,且文件名相等
        {
            temp = i;//文件存在
            break;
        }
    }
    //要刪除的目錄不存在
    if(temp == -1) {
        printf("rmdir: failed to remove '%s': No such file or directory\n",dirname);
        if(fd!=-1)
            close(fd);
        ptrcuridr=tempp;
        return 0;
    }
    //判斷子目錄是否爲空,不包括0和1,也能夠用length,懶得用
    DirFile *dirson=(DirFile*)(disk->Data[dir->fcb[temp].first-8]);
    int flag=-1;
    for(int i=2; i < FCBCOUNT; i++ ) {
        if (dir->fcb[i].free == 1){
            flag=1;
            break;
        }
    }
    //要刪除的目錄不爲空
    if(flag==-1)
    {
        printf("rmdir: failed to remove '%s': Directory not empty\n",dirname);
        if(fd!=-1)
            close(fd);
        ptrcuridr=tempp;
        return 0;
    }
    //檢查目錄是否已打開,打開就關閉
    //回收該目錄文件所佔據的磁盤塊,修改FAT
    disk->FAT1[dir->fcb[temp].first]=disk->FAT1[dir->fcb[temp].first]=0;
    //當前目錄文件中清空該目錄文件的目錄項,memset清理乾淨
    memset(&(dir->fcb[temp]),0,sizeof(dir->fcb[temp]));
    //修改長度,表項的fcbstate置爲1
    ptrcuridr->fcbstate=1;
    ptrcuridr->fcb.length--;//不包括.和..的
    /*-----------------恢復現場-------------*/
    if(fd!=-1)
        close(fd);
    ptrcuridr=tempp;
    return 1;
}

cd.cpp

分析

  • 善於利用open_path十分簡單的實現一個跳轉到任意路徑的函數

代碼

#include "OS.h"
int open(char *filename);
int close(int fd);
int open_path(char *dirname);
/*--------------全局變量-------------------------*/
extern char* myvhard;//虛擬磁盤起始地址
extern string currentdir;//當前目錄
extern string cmd; //讀取指令
extern USEROPEN openfilelist[MAXOPENFILE];//文件打開表
extern USEROPEN *ptrcuridr;//當前目錄在文件打開表的位置
extern DISK* disk;//將內容結構化
extern char command[50];//文件名標示符

/*----------------------更改當前目錄函數---------------------*/
int cd(char *dirname) {
        USEROPEN *temp = ptrcuridr;//暫時保管一下ptrcuridr原始值,可能要回溯
        int fd=open_path(dirname);
        if (fd != -1) {
            //關掉舊的描述符
           int old=temp->pos;
            //獲取舊的描述符
            if (old != 0)   //根目錄描述符不關
                close(old);
            //工做目錄指向它
            ptrcuridr = openfilelist + fd;
            //當前目錄賦值
            currentdir= ptrcuridr->dir ;
            currentdir+= '/';
            currentdir+= ptrcuridr->fcb.filename;
            return 0;
        }
        else {
            ptrcuridr = temp;
            printf("No such file or directory\n");
            return 0;
        }
    }

#文件操做

creat.cpp

分析

  • 有了open_path so easy

    代碼

    #include "OS.h"
    int close(int fd);
    int open_path(char dirname);
    int FileSubstr(char
    str);
    /--------------全局變量-------------------------/
    extern char* myvhard;//虛擬磁盤起始地址
    extern string currentdir;//當前目錄
    extern string cmd; //讀取指令
    extern USEROPEN openfilelist[MAXOPENFILE];//文件打開表
    extern USEROPEN ptrcuridr;//當前目錄在文件打開表的位置
    extern DISK
    disk;//將內容結構化
    extern char command[50];//文件名標示符

    int creat(char filename){
    //爲新文件分配一個空閒打開文件表項,若是沒有空閒表項就返回 -1
    //檢查打開文件表是否還有空表項,沒有報錯,有則記錄
    int OpenFileaddr=-1;
    for(int i=0;i<MAXOPENFILE;i++) {
    if (openfilelist[i].topenfile == 0) {
    OpenFileaddr=i;
    }
    }
    //沒有空表了
    if(OpenFileaddr==-1) {
    printf("File open table is full \n");
    return -1;
    }
    /
    -----------打開路徑所指的父目錄---------/
    char newdir[20];
    char dirpath[60];
    USEROPEN
    tempp = ptrcuridr;//暫時保管一下ptrcuridr原始值,可能要回溯
    int k=FileSubstr(filename),fd=-1;
    if(k!=-1) {
    filename[k] = 0;
    memset(newdir, 0, sizeof(newdir));
    memset(dirpath, 0, sizeof(dirpath));
    strcpy(newdir, filename + k + 1);
    strcpy(dirpath, filename);
    fd = open_path(dirpath);
    if(fd!=-1) {
    ptrcuridr = openfilelist + fd;
    filename = newdir;
    }
    else {
    printf("error\n");
    return -1;
    }
    }
    //檢查重名
    int BlockDirNum = (ptrcuridr->fcb).first;
    DirFile dir = (DirFile ) disk->Data[BlockDirNum - 8];
    int temp = -1,DirFreeItems =-1;
    for (int i = 0; i < FCBCOUNT; i++) {
    if (dir->fcb[i].free == 1 &&
    strcmp(dir->fcb[i].filename, filename) == 0)//表項被使用,且是目錄,且文件名相等
    {
    temp = i;//有重名,可能文件,可能文件夾
    break;
    }
    else if (dir->fcb[i].free == 0) {
    DirFreeItems = i;//目錄空閒表項
    }
    }
    //若是文件名已存在,報錯並退出
    if(temp!=-1)
    {
    if(fd!=-1)
    close(fd);
    ptrcuridr=tempp;
    printf("creat: cannot create file '%s': File exists\n",filename);
    return 0;
    }
    //若是沒有空閒位置,報錯退出
    if(DirFreeItems==-1)
    {
    printf("creat: cannot create file '%s': Directory is full \n",filename);
    if(fd!=-1)
    close(fd);
    ptrcuridr=tempp;
    return 0;
    }
    //檢查FAT中是否有空閒的盤塊
    int FATFreeItems=-1;
    for(int i = 0;i < BLOCKCOUNT;i++)
    {
    if(disk->FAT1[i] == 0) {//沒被使用的塊標記爲0
    FATFreeItems=i;//找到了一個空閒塊
    break;
    }
    }
    //若是FAT沒有空閒塊,報錯退出
    if(FATFreeItems==-1)
    {
    printf("mkdir: cannot create directory '%s': Disk is full \n",filename);
    if(fd!=-1)
    close(fd);
    ptrcuridr=tempp;
    return 0;
    }
    /----------------開始新建文件-------------------/
    //修改長度,fcbstate置爲1
    ptrcuridr->fcbstate=1;
    ptrcuridr->fcb.length++;//不包括.和..的
    //準備好新文件的FCB的內容,文件屬性爲數據文件,長度0.
    //分配FAT的空閒塊,-3表示被文件使用,-1表示文件結尾
    disk->FAT1[FATFreeItems]=disk->FAT2[FATFreeItems]=-1;
    //將改塊分配到 當前目錄的空閒項目下
    strcpy(dir->fcb[DirFreeItems].filename,filename);
    dir->fcb[DirFreeItems].free=1;//被使用
    dir->fcb[DirFreeItems].attribute=0;//是文件
    dir->fcb[DirFreeItems].first=FATFreeItems;//分配FAT空閒塊
    dir->fcb[DirFreeItems].length=0;
    dir->fcb[DirFreeItems].data=0;//時間以後弄
    dir->fcb[DirFreeItems].time=0;//時間以後弄
    //文件新建完畢
    //填寫文件打開表項
    openfilelist[OpenFileaddr].fcb=dir->fcb[DirFreeItems];
    char buffer[80];
    memset(buffer,0,sizeof(buffer));
    strcat(strcat(strcat(buffer,ptrcuridr->dir),"/"),ptrcuridr->fcb.filename);
    strcpy(openfilelist[OpenFileaddr].dir,buffer);
    strcpy(openfilelist[OpenFileaddr].fatherfilename,ptrcuridr->fcb.filename);
    openfilelist[OpenFileaddr].pos=OpenFileaddr;
    openfilelist[OpenFileaddr].count=0;
    openfilelist[OpenFileaddr].fcbstate=0;
    openfilelist[OpenFileaddr].topenfile=1;
    //關閉文件走人
    if(fd!=-1)
    close(fd);
    ptrcuridr=tempp;
    //返回文件描述符fd,此時的fd跟下標相同,通常不一樣.
    printf("File Creat Success,The fd is %d\n",OpenFileaddr);
    return OpenFileaddr;
    }

rm.cpp

定義

  • 記得遍歷鏈表釋放文件的空間
    • 鏈表的結尾是-1

代碼

#include "OS.h"
int close(int fd);
int open_path(char *dirname);
int FileSubstr(char *str);
/*--------------全局變量-------------------------*/
extern char* myvhard;//虛擬磁盤起始地址
extern string currentdir;//當前目錄
extern string cmd; //讀取指令
extern USEROPEN openfilelist[MAXOPENFILE];//文件打開表
extern USEROPEN *ptrcuridr;//當前目錄在文件打開表的位置
extern DISK* disk;//將內容結構化
extern char command[50];//文件名標示符
/*--------------------------刪除文件函數---------------------*/
int rm(char *filename){
/*--------------------------打開上級目錄---------------------*/
    char newdir[20];
    char dirpath[60];
    USEROPEN *tempp = ptrcuridr;//暫時保管一下ptrcuridr原始值,可能要回溯
    int k=FileSubstr(filename),fd=-1;
    if(k!=-1) {
        filename[k] = 0;
        memset(newdir, 0, sizeof(newdir));
        memset(dirpath, 0, sizeof(dirpath));
        strcpy(newdir, filename + k + 1);
        strcpy(dirpath, filename);
        fd = open_path(dirpath);
        if(fd!=-1) {
            ptrcuridr = openfilelist + fd;
            filename = newdir;
        }
        else {
            printf("error\n");
            return -1;
        }
    }
    //調用read,判斷目錄下文件是否存在
    int BlockDirNum = (ptrcuridr->fcb).first;
    DirFile *dir = (DirFile *) disk->Data[BlockDirNum - 8];
    int temp = -1;
    for (int i = 0; i < FCBCOUNT; i++) {
        if (dir->fcb[i].free == 1 && dir->fcb[i].attribute == 0 &&
            strcmp(dir->fcb[i].filename, filename) == 0)//表項被使用,且是文件,且文件名相等
        {
            temp = i;//文件存在
            break;
        }
    }
    //要刪除的目錄不存在
    if(temp == -1) {
        printf("rm: failed to remove '%s': No such file or directory\n",filename);
        if(fd!=-1)
            close(fd);
        ptrcuridr=tempp;
        return 0;
    }
    //檢查該文件是否打開,若打開則關閉
    char buffer[80];
    memset(buffer,0,sizeof(buffer));
    strcat(strcat(strcat(buffer,ptrcuridr->dir),"/"),ptrcuridr->fcb.filename);
    for(int i=1;i<MAXOPENFILE;i++) {
        //"."必定是被打開了
        if ((openfilelist[i].topenfile == 1 && strcmp(openfilelist[i].fcb.filename, filename) == 0 &&
             strcmp(openfilelist[i].dir,buffer) ==0 ))
        {
            printf(" The file  been opened,Now Close it !\n");
            close(i);
            break;
        }
    }
    //回收磁盤,一個鏈表
    int TEMP=0;
    for(int p=dir->fcb[temp].first;p!=-1;p=TEMP)
    {
        TEMP=disk->FAT1[p];
        disk->FAT1[p]=disk->FAT2[p]=0;
    }
    //清空該目錄項,free字段爲0,
    memset(&(dir->fcb[temp]),0,sizeof(dir->fcb[temp]));
    //修改長度,表項的fcbstate置爲1
    ptrcuridr->fcbstate=1;
    ptrcuridr->fcb.length--;//不包括.和..的
    /*-----------------恢復現場-------------*/
    if(fd!=-1)
        close(fd);
    ptrcuridr=tempp;
    return 1;
}

dowrite.cpp

分析

  • 每次循處理一塊磁盤
  • 文件指針轉換爲邏輯塊塊號blockno 和 塊內偏移blockoff;

代碼

#include "OS.h"
int open_path(char* dirname);
/*--------------全局變量-------------------------*/
extern char* myvhard;//虛擬磁盤起始地址
extern string currentdir;//當前目錄
extern string cmd; //讀取指令
extern USEROPEN openfilelist[MAXOPENFILE];//文件打開表
extern USEROPEN *ptrcuridr;//當前目錄在文件打開表的位置
extern DISK* disk;//將內容結構化
extern char command[16];//文件名標示符

/*---------------實際寫文件函數----------------*/
int dowrite(int fd,char *text,int len, char wstyle) {
    //申請1024字節的緩衝區buf
    char *buf = (char *) malloc(1024);
    if (buf == NULL) {
        printf("MALLOC ERROR b\n");
        return -1;
    }
    int tmplen = 0;
    int textpos = 0;
    int textlen = strlen(text);
    //將文件指針轉換爲邏輯塊塊號blockno 和 塊內偏移blockoff;

    /*--------------------分配-----------------*/
    while(tmplen<len) {
        int blockno = (openfilelist[fd].count) / 1024;
        int blockoff = (openfilelist[fd].count) % 1024;
        //尋找磁盤塊blockno
        int currentblock = 0;
        int cnt = 0;
        for (int p = openfilelist[fd].fcb.first; p != -1; p = disk->FAT1[p]) {
            cnt++;
            currentblock = p;
            if (cnt == blockno + 1)
                break;
        }
        int pre = currentblock;
        if (cnt != blockno + 1)//若是找不到這樣的一塊,那麼還須要給它分配blockno+1-cnt塊
        {
            //從currentblock開始分配
            for (int i = 1; i <= blockno + 1 - cnt; i++) {
                //檢查FAT中是否有空閒的盤塊
                int FATFreeItems = -1;
                for (int i = 0; i < BLOCKCOUNT; i++) {
                    if (disk->FAT1[i] == 0) {//沒被使用的塊標記爲0
                        FATFreeItems = i;//找到了一個空閒塊
                        break;
                    }
                }
                //若是FAT沒有空閒塊,報錯退出
                if (FATFreeItems == -1) {
                    printf("FAT IS FULL\n");
                    return -1;
                }
                disk->FAT1[pre] = FATFreeItems;
                pre = FATFreeItems;
            }
        }
        //若是是覆蓋寫,或者塊內偏移off不等於0,則將blkno的虛擬磁盤塊所有寫入buff中,不然memset
        if (wstyle == 2 || blockoff != 0) {
            memcpy(buf, disk->Data[currentblock - 8], 1024);
        }
        //將text中的內容暫存到緩衝區buff的第off字節開始的位置,直到緩衝區滿
        for (int i = blockoff; i < 1024 && textpos < textlen && tmplen<len; i++) {
            buf[i] = text[textpos];
            textpos++;
            tmplen++;  //讀入長度
        }
        memcpy(disk->Data[currentblock - 8], buf, 1024);
        openfilelist[fd].count += tmplen;
    }
    free(buf);
    return tmplen;
}

filewrite.cpp

分析

  • 實際的寫函數

代碼

#include "OS.h"
int open_path(char* dirname);
int dowrite(int fd,char *text,int len, char wstyle);
/*--------------全局變量-------------------------*/
extern char* myvhard;//虛擬磁盤起始地址
extern string currentdir;//當前目錄
extern string cmd; //讀取指令
extern USEROPEN openfilelist[MAXOPENFILE];//文件打開表
extern USEROPEN *ptrcuridr;//當前目錄在文件打開表的位置
extern DISK* disk;//將內容結構化
extern char command[16];//文件名標示符

/*---------------寫文件函數----------------*/

int filewrite(int fd) {
    int way = 0;
    //檢查fd的有效性
    if (fd >= MAXOPENFILE || fd <= 0) {
        printf("filewirt  ERROR:Is not a legitimate fd \n");
        return -1;
    }else if(openfilelist[fd].topenfile==0){
        printf("filewrite ERROR:該文件沒有被打開\n");
        return -1;
    }
    while (1) {
        //提示等待用戶輸入寫方式
        printf(" ------Please enter the way to write---------\n ");
        //1 : 截斷寫 2: 覆蓋寫 3: 追加寫
        printf(" ------1:TRUNC 2:OVER 3:APPEND---------\n ");
        scanf("%d", &way);
        if (1 <= way && way <= 3) break;
        else printf("Input Error,Please Try Again\n");
    }
    // 若是是截斷寫,釋放文件除第一塊外的磁盤空間內容
    //內存用戶打開表中文件長度爲0,,讀寫指針置爲0
    if (way == 1) {
        //釋放文件除第一塊外的磁盤空間內容
        int TEMP = 0;
        int ok = 1;
        for (int p = openfilelist[fd].fcb.first; p != -1; p = TEMP) {
            TEMP = disk->FAT1[p];
            if (ok != 1) {
                disk->FAT1[p] = disk->FAT2[p] = 0;
            }
            else {
                ok = 0;
            }
        }
        //長度置爲0
        openfilelist[fd].fcb.length = 0;
        //讀寫指針置爲0
        openfilelist[fd].count = 0;
    }
        //若是是追加寫,修改文件的當前讀寫指針到文件的末尾
    else if (way == 3) {
        openfilelist[fd].count = openfilelist[fd].fcb.length;
    }
    //提示用戶,輸入內容經過CTRL+Z結束,用戶可分屢次輸入寫入內容,每次用回車結束
    printf(" Input CTRL+D end the input\n ");
    int temp=0;
    char buffer[3000];
    while(gets(buffer)!=0){
        int len=strlen(buffer);
        buffer[len]='\n';
        buffer[len+1]='\0';
        int ret=dowrite(fd,buffer,strlen(buffer),way);
        if(ret==-1) {
            return -1;
        }
        else temp+=ret;
    }
    //若是當前讀寫指針位置大於長度,則更新長度,並置fcbstate置1
    if(openfilelist[fd].count>openfilelist[fd].fcb.length) {
        openfilelist[fd].fcb.length = openfilelist[fd].count;
        openfilelist[fd].fcbstate=1;
    }
    //返回實際寫入的字節
    return temp;
}

doread.cpp

分析

  • 每次讀一片磁盤

    代碼

    #include "OS.h"
    int open_path(char* dirname);
    int dowrite(int fd,char text,int len, char wstyle);
    /
    --------------全局變量-------------------------/
    extern char
    myvhard;//虛擬磁盤起始地址
    extern string currentdir;//當前目錄
    extern string cmd; //讀取指令
    extern USEROPEN openfilelist[MAXOPENFILE];//文件打開表
    extern USEROPEN ptrcuridr;//當前目錄在文件打開表的位置
    extern DISK
    disk;//將內容結構化
    extern char command[16];//文件名標示符
    /------------------實際讀文件函數--------------------------/
    //text的指向那個讀出數據的用戶地址
    int doread(int fd,int len,char text){
    //申請1024字節的緩衝區buf
    char
    buf = (char *) malloc(1024);
    if (buf == NULL) {
    printf("MALLOC ERROR b\n");
    return -1;
    }
    int tmplen = 0;
    int textpos = 0;
    //將最終指針轉換爲邏輯塊塊號blockno 和 塊內偏移blockoff;
    while(tmplen<len) {
    int blockno = (openfilelist[fd].count) / 1024;
    int blockoff = (openfilelist[fd].count) % 1024;
    //尋找磁盤塊blockno
    int currentblock = 0;
    int cnt = 0;
    for (int p = openfilelist[fd].fcb.first; p != -1; p = disk->FAT1[p]) {
    cnt++;
    currentblock = p;
    if (cnt == blockno + 1)
    break;
    }

    memcpy(buf, disk->Data[currentblock - 8], 1024);
    
          //
          for (int i = blockoff; i < 1024 && tmplen<len && openfilelist[i].count<openfilelist[i].fcb.length; i++) {
              text[textpos] = buf[i];
              textpos++;
              tmplen++;  //讀入長度
              openfilelist[fd].count;
          }
          memcpy(disk->Data[currentblock - 8], buf, 1024);
      }
          free(buf);
          return tmplen;

    }

fileread.cpp

分析

  • 實際的讀函數

代碼

#include "OS.h"
int open_path(char* dirname);
int dowrite(int fd,char *text,int len, char wstyle);
int doread(int fd,int len,char *text);
/*--------------全局變量-------------------------*/
extern char* myvhard;//虛擬磁盤起始地址
extern string currentdir;//當前目錄
extern string cmd; //讀取指令
extern USEROPEN openfilelist[MAXOPENFILE];//文件打開表
extern USEROPEN *ptrcuridr;//當前目錄在文件打開表的位置
extern DISK* disk;//將內容結構化
extern char command[16];//文件名標示符

/*---------------讀文件函數----------------*/
const  int MAXSIZE=1024*50;
int fileread(int fd,int len){
    char text[MAXSIZE];
    memset(text,0,sizeof(text));
    //檢查fd的有效性
    if (fd >= MAXOPENFILE || fd <= 0) {
        printf("filewirt:Is not a legitimate fd \n");
        return -1;
    }else if(openfilelist[fd].topenfile==0){
        printf("filewrite ERROR:The File Don't Open\n");
        return -1;
    }
    //調用do_read()讀取指定文件的len字節內容到text[]中.
    int rt=doread(fd,len,text);
    //若是do_read()返回值爲負,則顯示出錯信息,不然將text[]中的內容顯示到屏幕上;
    if(rt==-1){
        printf("READ FAIL");
        return -1;
    }else{
        //輸出text的內容
         for(int i=0;i<len;i++){
             printf("%c",text[i]);
         }
          printf("\n");
    }
}

exitsys.cpp

分析

  • 保存並退出
  • 關閉全部打開的文件

代碼

#include "OS.h"
int open_path(char* dirname);
int close(int fd);
/*--------------全局變量-------------------------*/
extern char* myvhard;//虛擬磁盤起始地址
extern string currentdir;//當前目錄
extern string cmd; //讀取指令
extern USEROPEN openfilelist[MAXOPENFILE];//文件打開表
extern USEROPEN *ptrcuridr;//當前目錄在文件打開表的位置
extern DISK* disk;//將內容結構化
extern char command[16];//文件名標示符

/*--------------退出文件系統函數------------------*/
void exitsys(){
    FILE * fd=fopen("myfsys","w");
    //關閉全部打開的文件
    for(int i=0;i<MAXOPENFILE;i++){
        if(openfilelist[i].topenfile==1)
            close(i);
    }
    fwrite(myvhard,sizeof(char),DISKSIZE,fd);
    fclose(fd);
    free(myvhard);
    exit(0);
}

幾個可有可無的函數

#include "stdio.h"
void help()
{
    printf("\n");
    printf("-----------------------help------------\n");
    printf("format         :-------Format The Disk.\n");
    printf("exit           :-------Exit OS File System AND **NOT SAVE**\n");
    printf("exitsys        :-------Exit OS File System AND SAVE")
    printf("cd     dirname :-------Change Directory\n");
    printf("mkdir  dirname :-------Make Directory.\n");
    printf("rmdir  dirname :-------Delete Directory.\n");
    printf("ls     dirname :-------List Directory .\n");
    printf("creat  filename:-------Creat File\n");
    printf("write  fd      :-------Wirte File\n");
    printf("read   fd      :-------Read File\n");
    printf("rm     filename:-------Remove File\n");
    printf("open   filename:-------Open File\n");
    printf("close  fd      :-------Close File\n");
    printf("open_path\n");
    printf("--------------------------------------\n\n");
}

和本身實現的分割字符串

//
// 切割字符串,例如/A/B/C/D 切割成 /A/B/C 和 D
//
#include "OS.h"

/*--------------全局變量-------------------------*/
extern char* myvhard;//虛擬磁盤起始地址
extern string currentdir;//當前目錄
extern string cmd; //讀取指令
extern USEROPEN openfilelist[MAXOPENFILE];//文件打開表
extern USEROPEN *ptrcuridr;//當前目錄在文件打開表的位置
extern DISK* disk;//將內容結構化
extern char command[50];//文件名標示符
/*-----------------------------------------------*/

int FileSubstr(char *str){
    int len=strlen(str);
    int cnt=0,flag=0;
    for(int i=1;i<len-1;i++)
    {
        if(str[i]=='/')
        {
            cnt++;
            flag=i;
        }
    }
    if(cnt==0) return -1;
    else return flag;
}
相關文章
相關標籤/搜索