zoukankan      html  css  js  c++  java
  • linux文件系统模拟

    #include "stdio.h"  
    #include <stdlib.h>  
    //#include <conio.h>  
    #include <string.h> 
    #include"unistd.h" 
     
    int physic[100];    //文件地址缓冲区 
    int style=1;     //文件的类型 
    char cur_dir[10]="root";  //当前目录   
     
    struct command 
    { 
        char com[10]; 
    }cmd[12]; 
     
    struct block 
    { 
        int n;      //空闲的盘快的个数 
        int free[50];    //存放空闲盘快的地址 
        int a;      //模拟盘快是否被占用 
    }memory[20449]; 
     
    struct block_super 
    { 
        int n;      //空闲的盘快的个数 
        int free[50];    //存放进入栈中的空闲块 
        int stack[50];    //存放下一组空闲盘快的地址 
    }super_block; 
     
    struct node      //i结点信息 
    { 
        int file_style;    //i结点 文件类型 
        int file_length;   //i结点 文件长度 
        int file_address[100];  //i结点 文件的物理地址 
    } i_node[640]; 
     
    struct dir      //目录项信息 
    { 
        char file_name[10];   //文件名 
        int  i_num;     //文件的结点号 
        char dir_name[10];   //文件所在的目录 
    } root[640]; 
     
    void format()     //格式化 
    { 
        int i,j,k; 
        super_block.n=50; 
        for(i=0;i<50;i++)     //超级块初始化 
        {  
            super_block.free[i]=i;   //存放进入栈中的空闲块 
            super_block.stack[i]=50+i;  //存放下一组的盘块 
        } 
         
        for(i=0;i<640;i++)     //i结点信息初始化 
        { 
            for(j=0;j<100;j++) 
            { 
                i_node[i].file_address[j]=-1;//文件地址 
            } 
            i_node[i].file_length=-1;  //文件长度 
            i_node[i].file_style=-1;  //文件类型 
        } 
         
        for(i=0;i<640;i++)     //根目录区信息初始化 
        { 
            strcpy(root[i].file_name,""); 
            root[i].i_num=-1; 
            strcpy(root[i].dir_name,""); 
        }  
        for(i=0;i<20449;i++)     //存储空间初始化   
        { 
            memory[i].n=0;      //必须有这个 
            memory[i].a=0;       
            for(j=0;j<50;j++) 
            { 
                memory[i].free[j]=-1; 
            } 
        } 
        for(i=0;i<20449;i++)    //将空闲块的信息用成组链接的方法写进每组的最后一个块中 
        {         //存储空间初始化 
             
            if((i+1)%50==0) 
            { 
                k=i+1; 
                for(j=0;j<50;j++) 
                { 
                    if(k<20450) 
                    { 
                        memory[i].free[j]=k;//下一组空闲地址 
                        memory[i].n++;  //下一组空闲个数   注意在memory[i].n++之前要给其赋初值 
                        k++; 
                    } 
                    else 
                    { 
                        memory[i].free[j]=-1; 
                    } 
                } 
                memory[i].a=0;    //标记为没有使用 
                continue;     //处理完用于存储下一组盘块信息的特殊盘块后,跳过本次循环 
            } 
            for(j=0;j<50;j++) 
            { 
                memory[i].free[j]=-1; 
            } 
            memory[i].n=0;   
        } 
        printf("已经初始化完毕
    "); 
        printf("进入linux文件系统模拟............
    "); 
    } 
     
    void write_file(FILE *fp)    //将信息读入系统文件中 
    { 
        int i; 
        fp=fopen("system","wb"); 
        for(i=0;i<20449;i++) 
        { 
            fwrite(&memory[i],sizeof(struct block),1,fp); 
        } 
        fwrite(&super_block,sizeof(struct block_super),1,fp); 
         
        for(i=0;i<640;i++) 
        { 
            fwrite(&i_node[i],sizeof(struct node),1,fp); 
        } 
        for(i=0;i<640;i++) 
        { 
            fwrite(&root[i],sizeof(struct dir),1,fp); 
        } 
        fclose(fp); 
    } 
     
    void read_file(FILE *fp)   //读出系统文件的信息 
    { 
        int i; 
        fp=fopen("system","rb"); 
        for(i=0;i<20449;i++) 
        { 
            fread(&memory[i],sizeof(struct block),1,fp); 
        } 
         
        fread(&super_block,sizeof(struct block_super),1,fp); 
         
        for(i=0;i<640;i++) 
        { 
            fread(&i_node[i],sizeof(struct node),1,fp); 
        } 
         
        for(i=0;i<640;i++) 
        { 
            fread(&root[i],sizeof(struct dir),1,fp); 
        }  
        fclose(fp); 
    } 
     
    void callback(int length)    //回收磁盘空间 
    { 
        int i,j,k,m,q=0; 
        for(i=length-1;i>=0;i--) 
        { 
            k=physic[i];     //需要提供要回收的文件的地址 
            m=49-super_block.n;    //回收到栈中的哪个位置 
            if(super_block.n==50)   //注意 当super_block.n==50时 m=-1;的值 
            {        //super_block.n==50的时候栈满了,要将这个栈中的所有地址信息写进下一个地址中 
                for(j=0;j<50;j++) 
                { 
                    memory[k].free[j]=super_block.free[j]; 
                } 
                super_block.n=0;  
                memory[k].n=50; 
            } 
            memory[k].a=0;  
            if(m==-1) 
            { 
                m=49;      //将下一个文件地址中的盘块号回收到栈底中,这个地址中存放着刚才满栈的地址的信息  
            } 
            super_block.free[m]=physic[i]; //将下一个文件地址中的盘块号回收到栈中 
            super_block.n++; 
        } 
    } 
     
    void allot(int length)     //分配空间 
    { 
        int i,j,k,m,p; 
        for(i=0;i<length;i++) 
        { 
            k=50-super_block.n;    //超级块中表示空闲块的指针 
            m=super_block.free[k];   //栈中的相应盘块的地址 
            p=super_block.free[49];   //栈中的最后一个盘块指向的地址 
            if(m==-1||memory[p].a==1)  //检测是否还有下一组盘块 
            { 
                printf("内存不足,不能够分配空间
    "); 
                callback(length); 
                break; 
            } 
            if(super_block.n==1) 
            {   
                memory[m].a=1;    //将最后一个盘块分配掉 
                physic[i]=m; 
                super_block.n=0;    
                for(j=0;j<memory[m].n;j++) //从最后一个盘块中取出下一组盘块号写入栈中 
                {  
                    super_block.free[j]=memory[m].free[j]; 
                    super_block.n++; 
                } 
                continue;     //要跳过这次循环,下面的语句在IF中已经执行过 
            } 
            physic[i]=m;     //栈中的相应盘块的地址写进 文件地址缓冲区 
            memory[m].a=1;   
            super_block.n--; 
        } 
    } 
     
    void create_file(char filename[],int length) //创建文件 
    { 
        int i,j; 
        for(i=0;i<640;i++) 
        { 
            if(strcmp(filename,root[i].file_name)==0) 
            { 
                printf("文件已经存在,不允许建立重名的文件
    "); 
                return; 
            } 
        } 
        for(i=0;i<640;i++) 
        { 
            if(root[i].i_num==-1) 
            { 
                root[i].i_num=i; 
                strcpy(root[i].file_name,filename); 
                strcpy(root[i].dir_name,cur_dir);  //把当前目录名 给新建立的文件 
                i_node[i].file_style=style; 
                i_node[i].file_length=length; 
                allot(length); 
                for(j=0;j<length;j++) 
                { 
                    i_node[i].file_address[j]=physic[j]; 
                } 
                break; 
            } 
        } 
    } 
     
    void create_dir(char filename[])    //创建目录 
    { 
        style=0;         //0代表文件类型是目录文件 
        create_file(filename,4); 
        style=1;         //用完恢复初值,因为全局变量,否则 
    } 
    void del_file(char filename[])     //删除文件 
    { 
        int i,j,k; 
        for(i=0;i<640;i++) 
        { 
             
            if(strcmp(filename,root[i].file_name)==0)    
            {  
                k=root[i].i_num; 
                for(j=0;j<i_node[k].file_length;j++) 
                { 
                    physic[j]=i_node[k].file_address[j]; 
                } 
                callback(i_node[k].file_length); //调用 回收函数 
                for(j=0;j<100;j++)     //删除文件后要将文件属性和目录项的各个值恢复初值 
                { 
                    i_node[k].file_address[j]=-1; //地址恢复初值 
                } 
                strcpy(root[i].file_name,"");  //文件名恢复初值 
                root[i].i_num=-1;     //目录项的I结点信息恢复初值 
                strcpy(root[i].dir_name,"");  //目录项的文件目录信息恢复初值 
                i_node[k].file_length=-1;   //文件长度恢复 
                i_node[k].file_style=-1;   //文件类型恢复初值 
                break; 
            }  
        } 
        if(i==640) 
        { 
            printf("不存在这个文件
    "); 
        }  
    } 
     
    void del_dir(char filename[])     //删除目录   需要判断目录下时候为空,不为空就不删除 
    { 
        int i,j,k; 
        for(i=0;i<640;i++)       //还要加条件判断要删除的目录是不是当前目录 
        { 
            k=root[i].i_num;      //找到目录名字 
            if( strcmp(root[i].file_name,filename)==0 && strcmp(cur_dir,filename)!=0 && (i_node[k].file_style)==0 )  
            { 
                 
                for(j=0;j<640;j++) 
                { 
                    if(strcmp(filename,root[j].dir_name)==0) 
                    { 
                        printf("目录不为空不能直接删除
    "); 
                        break; 
                    } 
                } 
                if(j==640) 
                { 
                    del_file(filename); 
                    break; 
                } 
                 
                break; 
            } 
        } 
        if(i==640) 
        { 
            printf("这个不是目录文件 或者不存在这个目录,或者你要删除的是当前目录
    "); 
        }  
         
    }  
    void display_curdir()         //显示当前目录下的文件列表 
    { 
        int i,k; 
        printf("		文件名字  文件类型  文件长度  所属目录
    "); 
        for(i=0;i<640;i++) 
        { 
            if(strcmp(cur_dir,root[i].dir_name)==0)   //查询文件中 所在目录信息和当前目录信息相同的数据 
            { 
                k=root[i].i_num; 
                printf("		  %s	",root[i].file_name);  //文件名 
                printf("	%d	",i_node[k].file_style);  //文件的类型 
                printf("%d	",i_node[k].file_length);  //文件的长度 
                printf("%s
    ",root[i].dir_name);   //文件所在的目录 
            } 
        } 
    } 
     
    void display_dir(char filename[])     //进入指定的目录   
    { 
        int i,k;   
        for(i=0;i<640;i++) 
        { 
            k=root[i].i_num;       //判断文件类型是不是目录类型 
            if((strcmp(filename,root[i].file_name)==0) && (i_node[k].file_style==0))     
            { 
                strcpy(cur_dir,filename);    //将要进入的指定目录设置为当前目录  赋值不要反了strcpy(目的,源) 
                break; 
            } 
        } 
        if(i==640) 
        { 
            printf("没有这个目录
    "); 
        } 
    } 
    void open_file(char filename[])        //打开文件 
    { 
        int i,j,k; 
        printf("		文件名字  文件类型  文件长度  所属目录
    "); 
        for(i=0;i<640;i++) 
        { 
            k=root[i].i_num; 
            if(strcmp(filename,root[i].file_name)==0 && (i_node[k].file_style==1)) 
            { 
                printf("		  %s	",root[i].file_name);   //文件名 
                printf("	%d	",i_node[k].file_style);   //文件的类型 
                printf("%d	",i_node[k].file_length);   //文件的长度 
                printf("%s
    ",root[i].dir_name);    //文件所在的目录 
                printf("		文件占用的物理地址
    "); 
                for(j=0;j<i_node[k].file_length;j++)   //显示物理地址 
                {   
                    printf("%d  ",i_node[k].file_address[j]); //文件具体占用的盘块号 
                } 
                printf("
    "); 
                break; 
            }  
        } 
        if(i==640) 
        { 
            printf("没有这个文件 或者这个文件不是正规文件
    "); 
        } 
    } 
     
    void back_dir()         //返回上一级目录 
    { 
        int  i,k; 
        for(i=0;i<640;i++)       //查询和当前目录名相同的目录文件名 
        { 
            k=root[i].i_num; 
            if(strcmp(cur_dir,root[i].file_name)==0 && (i_node[k].file_style==0))   
            { 
                strcpy(cur_dir,root[i].dir_name); //将查询到的目录文件名  所在的目录赋值给当前目录 
            } 
        } 
    } 
    void display_sys()        //显示系统信息(磁盘使用情况) 
    { 
        int i,m,k=0; 
        for(i=0;i<20449;i++) 
        { 
            if(memory[i].a==0) 
                k++; 
        } 
        m=20449-k; 
        printf("空闲的盘块数是:	"); 
        printf("%d
    ",k); 
        printf("使用的盘块数是:	"); 
        printf("%d
    ",m); 
    } 
     
    void help()          //显示帮助信息 
    { 
        printf("注意:创建的文件长度 < 100
    
    "); //说明文件 
        printf("0.初始化-------------------------format
    "); 
        printf("1.查看当前目录文件列表-----------dir
    "); 
        printf("2.创建文件---------------------create-----(create  + 空格 + 文件名 + 文件长度)  
    "); 
        printf("3.打开文件-----------------------cat-----(cat + 空格 + 文件名)  
    "); 
        printf("4.删除文件-----------------------del-----(del + 空格 + 文件名) 
    "); 
        printf("5.创建目录-----------------------md------(md  + 空格 + 目录名)  
    "); 
        printf("6.删除目录-----------------------deldir--(del + 空格 + 目录名)
    "); 
        printf("7.进入当前目录下的指定目录-------cd--------(cd + 空格 + 目录名)
    "); 
        printf("8.返回上一级目录-----------------cd..  
    "); 
        printf("9.查看系统信息-------------------ls    
    "); 
        printf("10.显示帮助命令-----------------help  
    "); 
        printf("11.退出文件模拟------------------exit  
    "); 
    } 
    void main()          //主函数 
    { 
        char tmp[10],com[10],tmp1[10],k; 
        struct command tmp2[10]; 
        int i, j=0,p,len=0; 
        FILE *fp; 
        help(); 
        strcpy(cmd[0].com,"format");    //将各个命令存进命令表 
        strcpy(cmd[1].com,"dir"); 
        strcpy(cmd[2].com,"cat"); 
        strcpy(cmd[3].com,"ls"); 
        strcpy(cmd[4].com,"md"); 
      
    strcpy(cmd[5].com,"create"); 
        strcpy(cmd[6].com,"del"); 
        strcpy(cmd[7].com,"deldir"); 
        strcpy(cmd[8].com,"cd"); 
        strcpy(cmd[9].com,"cd.."); 
        strcpy(cmd[10].com,"help"); 
        strcpy(cmd[11].com,"exit"); 
        if((fp=fopen("system","rb"))==NULL)   //判断系统文件是否存在 
        { 
            printf("can not open file
    "); 
            printf("format the disk  Y / N 
    "); 
            scanf("%c",&k); 
            if(k=='y') 
                format();  
        } 
        else 
        { 
            read_file(fp);       //读取系统文件的内容 
        } 
         
        while(1) 
        { 
            j=0;         //必须重新给恢复0否则出错 
            strcpy(tmp,cur_dir); 
            while(strcmp(tmp,"root")!=0) 
            { 
                for(i=0;i<640;i++) 
                { 
                    p=root[i].i_num; 
                    if(strcmp(tmp,root[i].file_name)==0 && (i_node[p].file_style==0)) 
                    { 
                        strcpy(tmp2[j].com,tmp); 
                        j++; 
                        strcpy(tmp,root[i].dir_name); 
                    } 
                } 
            } 
             
            strcpy(tmp2[j].com,tmp); 
            for(i=j;i>=0;i--) 
            { 
                printf("%s/",tmp2[i].com);  
            } 
             
            scanf("%s",com);       //输入命令并且查找命令的相关操作 
            for(i=0;i<12;i++)        
            { 
                if(strcmp(com,cmd[i].com)==0) 
                { 
                    p=i; 
                    break; 
                } 
            } 
            if(i==12)         //如果没有这个语句以后输入的命令都和第一次输入的效果一样 
            { 
                p=13; //随便的一个值 
            } 
            switch(p) 
            { 
            case 0: format();       //初始化 
                break; 
            case 1: display_curdir();     //查看当前目录下的文件列表       
                break; 
            case 2: scanf("%s",tmp);     //查看文件  
                open_file(tmp);   
                break; 
            case 3: display_sys();      //查看系统信息 
                break; 
            case 4:scanf("%s",tmp);      //创建目录     
                create_dir(tmp);   
                break; 
            case 5: scanf("%s",tmp);     //创建文件  
                scanf("%d",&len); 
                create_file(tmp,len);   
                break; 
            case 6: scanf("%s",tmp);     //删除文件 
                for(i=0;i<640;i++)     //判断文件是不是正规文件 
                { 
                    j=root[i].i_num; 
                    if(strcmp(tmp,root[i].file_name)==0 && (i_node[j].file_style)==1) 
                    { 
                        del_file(tmp); 
                        break; 
                    } 
                } 
                if(i==640) 
                { 
                    printf("这个不是正规文件文件
    "); 
                }      
                break; 
            case 7:  
                scanf("%s",tmp);     //删除目录 
                del_dir(tmp);    
                break; 
            case 8: scanf("%s",tmp1);     //进入当前目录下的指定目录   相当于进入目录  cd  +  目录名 
                display_dir(tmp1); 
                break; 
            case 9: back_dir();       //返回上一级目录 
                break; 
            case 10:help(); 
                break; 
            case 11:write_file(fp);      //将磁盘利用信息写进系统文件,退出 
                return; 
            default:printf("没有这个命令
    "); 
                break; 
            } 
        } 
    }  

  • 相关阅读:
    将变量名变为字符串
    sqlte3 的约束
    sqlte3 的基本使用4
    sqlite 的基本使用3
    sqlite 的基本使用2
    sqlite 的基本使用1
    TCP和UDP的区别(转)
    Mac 如何优雅的使用Microsoft office
    RGB和HSV颜色空间
    腾讯云视频开发相关参考
  • 原文地址:https://www.cnblogs.com/umgsai/p/3908211.html
Copyright © 2011-2022 走看看