当前位置:网站首页>OS Experiment 7 [document management]

OS Experiment 7 [document management]

2022-06-10 08:04:00 Book opens autumn maple

Catalog

One 、 The experiment purpose

Two 、 Experimental content

3、 ... and 、 The experimental requirements

Four 、 Design principle and related algorithms

5、 ... and 、 Result analysis  

1. Compile the file test08.cpp

2. format: Format command

3. mkdir hello: establish hello subdirectories

4. ls hello: Show hello Information in the directory

5. cd hello: Get into hello Catalog

6. create world 100: Create a new file world

7. cp world hello: Copy file wold File for hello

8. rename hello world2: Rename file hello by world2

9. rm world: Delete world file

10. rmdir hello: Delete hello Catalog

11. exit: Exit the system and save the message

6、 ... and 、 Source code  


One 、 The experiment purpose

1、 Explore 、 Understand and master FAT The organizational structure of the file system 、 Design principle and programming design gist .

2、 Through the experiment , master MSDOS Implementation method of file directory management in file system .

Two 、 Experimental content

1、 Design and implement a directory list for implementation ( similar DOS Under the DIR Order or Linux Of Shell command ls) Function of .

2、 Design and implement a function for renaming files .

3、 Design and implement a function for file deletion .

4*、 Design and implement the creation of new directories 、 A function that copies an existing file to a new file .

The prototypes of these functions are as follows :

int fd_ls();

int fd_rename(char *oldfilename,char *newfilename);

int fd_rm(char *name);

int fd_mkdir(char *name);

int fd_cp(char *source, char *destination);

3、 ... and 、 The experimental requirements

This experiment MSDOS Format on floppy disk . To implement these functions, you need a function that prepares the physical disk ( The letter Call the initialization code of the disk driver and other initialization codes selected to determine the disk geometry ): int fd_load(char driveLetter); Renaming and deleting files , You need to find the file , File deletion also involves traversal FAT Link in , Set up FAT And mark it as unused , Update catalog entries . In the case of deletion , Pay attention to file hiding 、 Read only and system properties . Any file with this attribute cannot be deleted .

Besides , Mission 4 We still need fd_open()fd_close()fd_read()fd_write() Function to write byte stream .

Four 、 Design principle and related algorithms

Want to complete the operating system algorithm , First of all, we should understand the terminology related to the operating system . Clarify the flow and purpose requirements of each algorithm . In order to simulate the process of related algorithms .

In general , Operating system , File management provides the following functions :

① Unified management of file storage space ( That is, external deposit ), Implement the allocation and recycling of storage space .
② Determine the storage location and storage form of document information .
③ Realize the mapping of files from namespace to external memory address space , That is to realize the access of files by name .
④ Effectively realize various control operations on documents ( Such as the establishment of 、 revoke 、 open 、 Close files, etc ) And access operations ( As read 、 Write 、 modify 、 Copy 、 Dump, etc )

In fact, it is to manage files .

This experiment defines the following data structure for the file :

class file:
    def __init__(self, uid, fid, name, status):
        self.uid = uid
        self.fid = fid
        self.name = name
        self.status = status

Defines the of the file id identification , file name , Status and so on .

5、 ... and 、 Result analysis  

1. Compile the file test08.cpp

g++ test08.cpp -o test08

2. format: Format command

3. mkdir hello: establish hello subdirectories

4. ls hello: Show hello Information in the directory

5. cd hello: Get into hello Catalog

6. create world 100: Create a new file world

7. cp world hello: Copy file wold File for hello

8. rename hello world2: Rename file hello by world2

9. rm world: Delete world file

10. rmdir hello: Delete hello Catalog

11. exit: Exit the system and save the message

6、 ... and 、 Source code  

create a file test08.cpp

vim test08.cpp
g++ test08.cpp -o test08
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <bitset>

using namespace std;
const int BLOCKNUM_SIZE=2;					// Disk block number size 
const int BLOCK_SIZE=1024;				    // The size of a disk block 
const int BLOCK_NUM=10001;				    // Number of disks 
const int DISK_SIZE=1024*1000*10;			// Disk size 
const int LIST_SIZE=32;						// Directory entry size 
const int MAP_SIZE=10001;						//MAP  length 
const int FATNUM=125;						//FAT Number of disks   The first block is useless 
const int FATLIST=512;					// Each coil opening FAT Number of records 
const int DATABEG=128;					// Data item start FAT Number 

struct FCB{
    char fname[8];						// file name 
    char exname[3];						// Extension 
    short  fnum;						// First block No 
    int length;							// file size ,   Directory, the file size is ;
};

struct fatid{
    short id[FATNUM*FATLIST];   //FAT  size 512 A record   A piece of 
}*FAT;

struct map{
    bitset<MAP_SIZE> maplist;
}*MAP;

struct DIR{
    struct FCB list[LIST_SIZE+1];
}*filedir;

int currentid=128;                  // At present FAT Number 
int currentdir=128;                 // Current directory block number initialization is +1   Since unit is not used 
char *file;                          // The first address of the disk 
char *FilePath="myfat";              //window File storage address 
FILE *fp;                           //window  File address 
string CURRENT="root\\";				// current path 
char  cmd[30];						// Input instruction 
char command[16];



/*
* Format the file storage 
* Create the root directory 
*
*/
void init(struct fatid *FAT){
    int i,j;
    for(i=1;i<FATNUM*FATLIST;i++)			// Block   Don't use 
    {
        if(i>DATABEG)
            FAT->id[i]=0;
        else
            FAT->id[i]=-1;
    }
}
void format(){
    bool i;
    FAT=(struct fatid *)(file+BLOCK_SIZE);                         // At present FAT Address 
    MAP=(struct map *)(file+(FATNUM+1)*BLOCK_SIZE);       // Initialization bit diagram 
    init(FAT);
    FAT->id[0]=9872;
    filedir=(struct DIR *)(file+(FATNUM+1+2)*BLOCK_SIZE);		  // Current directory pointer address 
    FAT->id[128]=-1;
    FAT->id[0]=9872-1;
    strcpy(filedir->list[0].fname,".");
    strcpy(filedir->list[0].exname,"dir");
    filedir->list[0].fnum=currentdir;
    filedir->list[0].length=0;
    strcpy(filedir->list[1].fname,"..");
    strcpy(filedir->list[1].exname,"dir");
    filedir->list[1].fnum=currentdir;
    filedir->list[1].length=0;
    fp=fopen(FilePath,"w+");
    fwrite(file,sizeof(char),DISK_SIZE,fp);
    fclose(fp);
    printf(" Initialization is complete , Now you can operate !\n\n");
}

/*
* Create subdirectories 
*/
int mkdir(char *str)
{
    int i,j;
    int blockid;			// About to create FAT Number 
    int blockdir;			// Number of directory block to be created 
    int listnum;			// Number in the catalog block 

    struct fatid *flagid;
    struct DIR *dir;        // Current directory pointer 
    struct map *MAP;
    struct fatid *FAT;

    if(strcmp(str,"")==0)
    {
        printf(" Directory name cannot be empty \n");
        return 0;
    }

    dir=(struct DIR *)(file+(currentdir)*BLOCK_SIZE);
    MAP=(struct map *)(file+(FATNUM+1)*BLOCK_SIZE);
    FAT=(struct fatid *)(file+BLOCK_SIZE);

    for(i=DATABEG+1;i<BLOCK_NUM;i++)   // from 128 Block data block   The actual block starts searching 
        {
        if(MAP->maplist[i]==0)
            break;

        }

    if(i>BLOCK_NUM)
    {
        printf(" Out of memory \n");
        return 0;
    }

    MAP->maplist[i]=1;				//map  Set and use 


    dir=(struct DIR *)(file+(currentdir)*BLOCK_SIZE);


    for(i=2;i<LIST_SIZE;i++)
    {
        if(strcmp(dir->list[i].fname,str)==0)
        {
            printf(" There is a folder with the same name under the directory \n");
            return 0;
        }
    }
    for(i=2;i<LIST_SIZE;i++)
    {

        if(strcmp(dir->list[i].fname,"")==0)			// There are empty directory blocks and no duplicate names , The first version is put together with the above loop , There is a case where the previously created directory is deleted , Directly covered by the same name 
            break;
        if(i>LIST_SIZE)
        {
            printf(" Out of memory \n");
            return 0;
        }
    }
    flagid=(struct fatid *)(file+BLOCK_SIZE);	//fat  First address 

    for(j=DATABEG+1;j<BLOCK_NUM;j++)
    {
        if(flagid->id[j]==0)
        {
            blockdir=j;
            break;
        }
    }

    strcpy(dir->list[i].fname,str);
    dir->list[i].fnum=blockdir;
    strcpy(dir->list[i].exname,"dir");
    dir->list[i].length=0;


    dir=(struct DIR *)(file+blockdir*BLOCK_SIZE);   // Create a root directory for the new directory entry 
    strcpy(dir->list[0].fname,".");
    strcpy(dir->list[0].exname,"dir");
    dir->list[0].fnum=blockdir;
    dir->list[0].length=0;

    strcpy(dir->list[1].fname,"..");
    strcpy(dir->list[1].exname,"dir");
    dir->list[1].fnum=currentdir;
    dir->list[1].length=0;

    flagid->id[j]=-1;                 // modify FAT   Directory tail 
    FAT->id[0]=FAT->id[0]-1;

    printf(" The directory has been successfully created %s \n",str);

    return 0;
}

/*
* Show directory 
*/
int listshow()
{
    int i,sumfile,sumdir,fl[100],dr[100];//fl  Is the number of the document ,dr Is the number of the directory 
    sumfile=sumdir=0;

    struct DIR *dir;
    struct fatid *FAT;

    dir=(struct DIR *)(file+currentdir*BLOCK_SIZE);

    for(i=0;i<LIST_SIZE;i++)
    {
        if(dir->list[i].length==0&&(strcmp(dir->list[i].fname,"")!=0)&&(dir->list[i].fnum!=0))			// For directory 
            {
            dr[sumdir]=i;
            sumdir++;

            }
        if(dir->list[i].length!=0&&strcmp(dir->list[i].fname,"")!=0)			// For directory 
            {
            fl[sumfile]=i;
            sumfile++;

            }


    }

    for(i=0;i<sumdir;i++)
        printf("   %s        Folder \n",dir->list[dr[i]].fname);

    for(i=0;i<sumfile;i++)
        printf("   %s       %s file \n",dir->list[fl[i]].fname,dir->list[fl[i]].exname);

    printf("\n");

    printf("\n Under this directory, there are %d  File , %d  A folder \n\n",sumfile,sumdir-2);
    return 0;
}

/*
* delete a sub dir 
*/
int rmdir(char *str)
{
    int  i;
    int blockid;
    int flag=0;
    //FAT Number 
    int blocknum;				// Directory block 

    struct fatid *FAT;
    struct DIR *dir;
    struct DIR *flagdir;		// Mark the directory block 


    char c='a';			   // Do user interaction 
    int m=2;				// Search for the directory items to be deleted from the third subdirectory item 

    FAT=(struct fatid *)(file+BLOCK_SIZE);
    dir=(struct DIR *)(file+currentdir*BLOCK_SIZE);			// Current directory pointer 
    MAP=(struct map *)(file+(FATNUM+1)*BLOCK_SIZE);


    for(i=2;i<LIST_SIZE;i++)
    {
        if(strcmp(dir->list[i].fname,str)==0)		// Find the subdirectory to delete 
            {
            break;
            }
    }

    if(i>LIST_SIZE)
    {
        printf(" The folder does not exist %s",str);
        return 0;
    }


    while(1)
    {
        printf(" Are you sure ?(Y/N)");
        cin>>c;
        if((c=='y'||c=='Y')||(c=='n'||c=='N'))
            break;

    }

    if(c=='n'||c=='N')
        return 0;

    blocknum=dir->list[i].fnum;

    flagdir=(struct DIR *)(file+blocknum*BLOCK_SIZE);

    while(m!=LIST_SIZE)
    {
        if(strcmp(flagdir->list[m].fname,"")!=0)
        {
            printf(" There are sub files or sub directories under this directory , The directory cannot be deleted ");
        }
        m++;
    }

    strcpy(dir->list[i].fname,"");		// Parent directory DIR
    strcpy(dir->list[i].exname,"");
    dir->list[i].fnum=0;


    strcpy(flagdir->list[0].fname,"");			// To delete a directory DIR
    strcpy(flagdir->list[0].exname,"");
    flagdir->list[0].fnum=0;

    strcpy(flagdir->list[1].fname,"");
    strcpy(flagdir->list[1].exname,"");
    flagdir->list[0].fnum=0;

    MAP->maplist[blocknum]=0;
    FAT->id[blocknum]=0;
    FAT->id[0]=FAT->id[0]+1;

    return 0;
}

/*
* Change the current directory (cd command )
*/
int changedir(char *str)
{
    int i,j;
    int blocknum;			// Current directory location 
    int flagnum;			//temp Directory location of 
    struct DIR * flagdir,*dir;
    struct fatid * FAT;
    string strflag;     // To change the currently displayed code 


    dir=(struct DIR *)(file+currentdir*BLOCK_SIZE);

    if(strcmp("..",str)==0)					// Determine whether it is an upper level directory 
        {
        blocknum=currentdir;
        if(dir->list[0].fnum==dir->list[1].fnum)	// Characteristics of the root directory 
            {
            return 1;
            }

        currentdir=dir->list[1].fnum;							// Change the current directory pointer 

        flagdir=(struct DIR *)(file+currentdir*BLOCK_SIZE);		// Go to the upper directory address 

        for(int j=0;j<LIST_SIZE;j++)
        {
            if(flagdir->list[j].fnum==blocknum)
            {
                strflag=flagdir->list[j].fname;
                break;

            }
        }
        CURRENT=CURRENT.substr(0,(CURRENT.length()-strflag.length())-1);
        return 1;
        }

    for(i=2;i<LIST_SIZE;i++)									// subdirectories 
        {
        if(strcmp(dir->list[i].fname,str)==0&&strcmp(dir->list[i].exname,"dir")==0)
        {
            currentdir=dir->list[i].fnum;
            break;
        }
        }


    if(i>LIST_SIZE)
    {
        printf(" The specified directory could not be found %s\n",str);
        return 0;
    }

    CURRENT=CURRENT+str+"\\";
    return 1;
}

/*
* create a file 
*/
int create(char *str,int length)
{
    //getfilename
    int i,j,l,t,k;
    int blockdir;
    int fid;		//FAT The first block number of 
    int flag;		// First block judgment of file 
    char name[8]={0};	// File name 
    char exname[3]={0};	// File extension 
    int templength;      	//temp file length 

    struct fatid * FAT;
    struct DIR *dir;
    struct map *MAP;

    dir=(struct DIR *)(file+(currentdir)*BLOCK_SIZE);
    MAP=(struct map *)(file+(FATNUM+1)*BLOCK_SIZE);
    FAT=(struct fatid *)(file+BLOCK_SIZE);
    templength=length;

    l=strlen(str);
    // Take file name 
    for(i=0;i<l;i++)
    {

        name[i]=str[i];
        if(str[i+1]=='.')
            break;
    }

    if(i>=8)
    {
        printf(" The file name is too long \n");
        return 0;
    }

    // De extension 
    j=0;
    i++;
    i++;// Remove points 
    k=l-i;
    for(j=0;j<k;j++)
    {

        if(str[i]=='\0')
            break;
        exname[j]=str[i];
        i++;
    }
    if(strcmp(name,"0")==0)
    {
        printf(" File name cannot be empty \n");
        return 0;
    }

    if(length>FAT->id[0])
    {
        printf(" File exceeds disk space \n");
        return 0;
    }


    for(i=2;i<LIST_SIZE;i++)
    {
        if(strcmp(dir->list[i].fname,name)==0&&strcmp(dir->list[i].exname,exname)==0)
        {
            printf(" Under this folder , There is already a file with the same name ");
            return 0;
        }
        if(strcmp(dir->list[i].fname,"")==0)
        {
            break;
        }

    }
    if(i>LIST_SIZE)
    {
        printf(" Out of memory \n");
        return 0;
    }
    strcpy(dir->list[i].fname,name);
    strcpy(dir->list[i].exname,exname);
    dir->list[i].length=length;

    flag=1;
    j=DATABEG+1;

    while(1){// Keep cycling 
        if(MAP->maplist[j]!=1)
        {
            if(!templength--)	// When length All assigned until 
                break;
            // The address of the previous block 
            if(flag)		// The first allocation is the first address of 
                {
                dir->list[i].fnum=j;		// Give the first block of the file 

                }
            MAP->maplist[j]=1;				//MAP Reduce 
            if(!flag)
            {
                FAT->id[t]=j;
                FAT->id[0]=FAT->id[0]-1;
            }
            t=j;
            flag=0;
        }
        j++;
    }
    FAT->id[t]=-1;
    FAT->id[0]=FAT->id[0]-1;
    return 1;
}

/**
 Copy file 
*/
int cp(char *str,char *newname)
{
    int i,j,k,l,length;
    char name[8]={0};	// File name 
    char exname[3]={0};	// File extension 
    struct DIR *dir;
    l=strlen(str);
    // Take file name 
    for(i=0;i<l;i++)
    {
        name[i]=str[i];
        if(str[i+1]=='.')
            break;
    }
    // De extension 
    j=0;
    i++;
    i++;// Remove points 
    k=l-i;
    for(j=0;j<k;j++)
    {

        if(str[i]=='\0')
            break;
        exname[j]=str[i];
        i++;
    }
    if(strcmp(newname,"")==0)
    {
        printf(" File name cannot be empty \n");
        return 0;
    }
    dir=(struct DIR *)(file+currentdir*BLOCK_SIZE);

    for(i=2;i<LIST_SIZE;i++)									// Sub file 
        {
        if(strcmp(dir->list[i].fname,name)==0&&strcmp(dir->list[i].exname,exname)==0)
            break;

        }
    if(i>LIST_SIZE)
    {
        printf(" The specified file could not be found %s\n",str);
        return 0;
    }
    length=dir->list[i].length ;
    create(newname,length);
}

/*
* Delete file 
*/
int delfile(char *str)
{
    int i,j,l,k;
    int blocknum;       // First block address to delete 
    int temp;
    char name[8]={0};	// File name 
    char exname[3]={0};	// File extension 
    char c='a';

    struct DIR *dir;
    struct fatid *FAT;
    struct map *MAP;

    l=strlen(str);
    // Take file name 
    for(i=0;i<l;i++)
    {

        name[i]=str[i];
        if(str[i+1]=='.')
            break;
    }


    // De extension 
    j=0;
    i++;
    i++;// Remove points 
    k=l-i;
    for(j=0;j<k;j++)
    {

        if(str[i]=='\0')
            break;
        exname[j]=str[i];
        i++;
    }


    if(strcmp(str,"")==0)
    {
        printf(" File name cannot be empty \n");
        return 0;
    }

    dir=(struct DIR *)(file+(currentdir)*BLOCK_SIZE);
    MAP=(struct map *)(file+(FATNUM+1)*BLOCK_SIZE);
    FAT=(struct fatid *)(file+BLOCK_SIZE);

    for(i=2;i<LIST_SIZE;i++)
    {
        if((strcmp(dir->list[i].fname,name)==0)&&(strcmp(dir->list[i].exname,exname)==0))
            break;

    }
    if(i>LIST_SIZE)
    {
        printf(" Can't find %s  file \n",str);
        return 0;
    }

    if(c=='n'||c=='N')
        return 0;

    blocknum=dir->list[i].fnum;
    dir->list[i].fnum=0;				// Restore the catalog entries 
    strcpy(dir->list[i].exname,"");
    strcpy(dir->list[i].fname,"");
    dir->list[i].length=0;


    // Handle FAT AND MAP  surface 

    while(FAT->id[blocknum]!=-1)
    {
        temp=FAT->id[blocknum];;
        FAT->id[blocknum]=0;
        FAT->id[0]=FAT->id[0]+1;
        MAP->maplist[blocknum]=0;
        blocknum=temp;
    }
    return 0;
}
/*
 * Rename file ( Copy the current file to a new file , And delete the current file )
 */

void rename(char *str,char *newname){
    cp(str,newname);
    delfile(str);
}

/**
 Exit the system 
*/
int exit()
{
    fp=fopen(FilePath,"w+");
    fwrite(file,sizeof(char),DISK_SIZE,fp);
    fclose(fp);
    free(file);
    return 1;
}


void welcome()
{
    // Welcome list 

    printf("--------------------------------------------------\n");
    printf("\n Here are the instructions \n");
    printf("format          :  Format the disk .\n");
    printf("exit            :  Safely exit the file system , Save information .\n");
    printf("mkdir  dirname  ;  Create subdirectories .\n");
    printf("rmdir  dirname  :  delete a sub dir .\n");
    printf("ls     dirname  :  Display the information under the current directory .\n");
    printf("cd     dirname  :  Change the current directory .\n");
    printf("create filename length :  Create a new file .\n");
    printf("rm     filename :  Delete file .\n");
    printf("cp oldname newname:  Copy file .\n");
    printf("rename oldname newname :  Rename file .\n");
    printf("\n--------------------------------------------\n");

    // Apply for virtual space 
    file=(char *)malloc(DISK_SIZE*sizeof(char));

    // load 
    if((fp=fopen(FilePath,"r"))!=NULL)
    {
        fread(file,sizeof(char),DISK_SIZE,fp);
        printf(" Load disk file %s File successfully , Now you can operate \n\n",FilePath);
    }else
    {
        printf(" This is the first time to use a file management system ");
    }


}

int main()
{
    int length;
    char newname[20];
    welcome();
    format();
    while(1)
    {
        cout<<CURRENT<<"#";
        cin>>cmd;
        if(strcmp(cmd,"format")==0){
            free(file);
            file=(char*)malloc(DISK_SIZE*sizeof(char));  // Reallocate space 
            format();
        }else if(strcmp(cmd,"mkdir")==0)
        {
            scanf("%s",command);
            mkdir(command);
        }else if(strcmp(cmd,"rmdir")==0)
        {
            scanf("%s",command);
            rmdir(command);
        }
        else if(strcmp(cmd,"ls")==0)
        {
            listshow();
        }else if(strcmp(cmd,"cd")==0)
        {
            scanf("%s",command);
            changedir(command);
        }else if(strcmp(cmd,"create")==0)
        {
            cin>>command>>length;
            create(command,length);
        }else if(strcmp(cmd,"cp")==0)
        {
            cin>>command>>newname;
            cp(command,newname);
        }else if(strcmp(cmd,"rm")==0)
        {
            scanf("%s",command);
            delfile(command);
        }
        else if (strcmp(cmd,"rename")==0){
            cin>>command>>newname;
            rename(command,newname);
        }
        else if(strcmp(cmd,"exit")==0){
            exit();
            break;
        }
        else {
            printf(" Invalid instructions , Please re-enter :\n");
        }
    }
    printf("Thank you for using my file system!\n");
    return 0;
}
原网站

版权声明
本文为[Book opens autumn maple]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/161/202206100748453363.html