0


使用C语言实现磁盘的文件管理系统

项目名称

磁盘文件管理系统

一、实验目的:

1.理解磁盘文件管理的概念和原理;

2.了解文件的逻辑结构和物理结构;

3.理解文件目录结构;

4.掌握磁盘存储空间管理、文件操作实现方法。

二、实验内容:

设计并实现一个简单的磁盘文件管理系统,用文件模拟磁盘,用数组模拟缓冲区。

要求实现:

1.支持多级目录结构,支持文件的绝对路径访问;

2.文件的逻辑结构采用流式(字节流)结构,物理结构采用链式结构中的显式链方式;

3.磁盘管理采用文件分配表;

4.实现文件操作命令:创建目录、列表目录、删除空目录、创建文件、删除文件、显示文件内容、打开文件、读文件、写文件(追加方式)、关闭文件、改变文件属性;

5.通过主函数对所实现的功能进行测试。

模拟磁盘的那个文件中存放的信息

开始菜单

正在上传…重新上传取消正在上传…重新上传取消

创建一个新的文件,需要输入已有的路径名

正在上传…重新上传取消正在上传…重新上传取消

Us目录中存放的文件为:

创建多级目录,可以创建不存在的目录列表

新创建的/d1目录中的内容

新创建的/d1/d2目录中的内容

显示文件中的信息,用单个字符的格式输出

往一个文件中追加方式写入

写入后的文件内容

删除前的目录信息

正在上传…重新上传取消正在上传…重新上传取消

删除一个目录/a

正在上传…重新上传取消正在上传…重新上传取消

删除后的目录信息

正在上传…重新上传取消正在上传…重新上传取消

删除不存在文件

正在上传…重新上传取消正在上传…重新上传取消

正在上传…重新上传取消正在上传…重新上传取消

正在上传…重新上传取消正在上传…重新上传取消

删除目录前的信息

正在上传…重新上传取消正在上传…重新上传取消

删除一个目录,这个目录不存在的情况

正在上传…重新上传取消正在上传…重新上传取消

删除目录前的信息

正在上传…重新上传取消正在上传…重新上传取消

删除目录/t

正在上传…重新上传取消正在上传…重新上传取消

删除后的目录内容

正在上传…重新上传取消正在上传…重新上传取消

改变文件的属性:

将普通文件改为系统文件

正在上传…重新上传取消正在上传…重新上传取消

修改后的目录信息

正在上传…重新上传取消正在上传…重新上传取消

显示FAT表中的分配情况

正在上传…重新上传取消正在上传…重新上传取消

  1. 本实验使用的是树形的目录结构,一个结点里面存储所有子节点的文件控制块,因此可以通过这个结点去控制子节点的一切活动,结点中存储有n个子目录控制块和字目录节点指针,只需要通过一个文件或目录的控制块所在结点的下标号就能控制这个目录的一切行为。
  2. 本实验将目录也视作是文件,对目录的操作和对文件的操作一样。
  3. 本使用使用了FAT 文件分配表,可以查看已经分配出去的磁盘块,和空闲的磁盘块。
  4. 本实验将所有的目录都读取到内存中,在项目关闭前,不改变磁盘中目录的内容,只有关闭时,将所有的目录信息重新写入磁盘文件。
  5. 磁盘有多少块,文件分配表就有多少项该文件的下一个磁盘块号应该存放在FAT的第i项,-1(,磁盘块号与FAT表项序号一一对应。
  6. 每项取值:若某文件的一个磁盘块号为i,则255)表示文件结束;为0表示这是一个空闲块;可以用一个非0、非-1、非有效块号的值(如254)表示一个故障盘块。
  7. 分配时查找值为0的项(设置一个“空闲块总数”变量可以提高分配下率!),并建立链表;回收时只需修改要回收的盘块对应表项的值。
  8. 实现的操作有创建文件(create_file)、打开文件(open_file)、关闭文件(close_file)、读文件(read_file)、写文件(write_file)、删除文件(delete_file)、显示文件内容(typefile) 、改变文件属性(change)、创建目录(md)、列表目录(dir)、删除空目录(rd) –用选择方式输入命令;
  9. 根目录以”/”作为根的名字

尚存问

代码:


#include<stdio.h>
#include<string.h>
#include<stdint.h >
#include<string.h>
#include<stdlib.h>
#include<io.h>

显示链中的FAT表要全在内存中存放
//typedef struct FAT{
//
//    int8_t num;
//    int8_t next;
//}FAT;

#define attribute_file 0b00000100

#define attribute_sys 0b00000010
#define attribute_onlyr 0b00000001
#define attribute_dir 0b00001000

//结构体定义区
typedef struct inode {
    char name[3];
    int8_t attribute;
    char type[2];
    int8_t startb;
    int8_t length;//字节个数
} inode;

typedef struct myFILE {
    int readpyl;
    int readb;
    int startb;
    int writeb;
    int writepyl;
    int length;
    int8_t logicB[10];
    inode *FCBp;
} myFILE;

typedef struct openFile {
    inode *FCB;
    myFILE *myfile;
    int flag;//标志是否存在
} openFile;

typedef struct openFileTable {
    openFile table[10];
    int num;
} openFileTable;

typedef struct DirBuff {
    inode DIRI[20];
    DirBuff* nextDIR[20];
    int num;

} DirBuff;

//函数声明区

//初始化和菜单
void menu();
void initDisk();
void showInode(inode FCB);
void initDiskDirBuff();
void showDir(char path[]);

//文件操作相关
int create_file();
int writeDir();
myFILE* open_file(char pathname[]);
int delete_file(char pathname[]);
void typefile(char pathname[]);
void myFwrite(void *ptr, size_t size, size_t num, myFILE* fp);
void change(char pathname[]);

//目录操作相关
//int md(inode *dirction);
int dir(char path[]);
int  find(DirBuff **DirB, int *Index, char pathname[], int mod);
int closeDir();
int writeDir(DirBuff*root, myFILE*fp);
int md(char pathname[]);

void showFAT();
void showFile(myFILE fp);
void rd(char pathname[]);

//int transform(inode *aNode,int8_t block[],int n,int mod);
size_t myFread(void *ptr, size_t size, size_t n, myFILE *fp);
int readDir(DirBuff **root, myFILE *fp);

//全局变量定义区
openFileTable table1;
FILE *disk;
inode dircationBuffBlock[3];
inode fileBuffBlock[5];
char PWD[20];
DirBuff *rootDir;

int freeblocknum;
//FAT fatBuff;

char rootname[30];

int8_t FAT[128];

int main() {

    int8_t block[64] = {0};
    system("color 80");
    int i = 0;
    if (access("disk", 0) == 0) {

        printf("磁盘文件存在\n");
        disk = fopen("disk", "rb+");
        fseek(disk, 64, SEEK_SET);
        fread(&FAT, sizeof(int8_t), 128, disk);
        freeblocknum = 0;
        for (i = 0; i < 128; i++) {
            if (FAT[i] == 0)
                freeblocknum++;
        }

        initDiskDirBuff();
//        showFAT();

    } else {

        printf("磁盘文件不存在\n");
        disk = fopen("disk", "wb+");
        for (i = 0; i < 128; i++) {
            fwrite(block, sizeof(int8_t), 64, disk);
        }

        FAT[0] = FAT[2] = FAT[3] = -1;
        FAT[1] = 2;

        fseek(disk, 64, SEEK_SET);
        fwrite(FAT, sizeof(int8_t), 128, disk);
        inode *ptinode = (inode*)malloc(sizeof(inode));

        ptinode->length = 0;
        ptinode->startb = -1;
        ptinode->name[0] = '/';
        ptinode->name[1] = 0;
        ptinode->attribute = attribute_dir;

        strcpy(ptinode->type, "d");
        fseek(disk, 3 * 64, SEEK_SET);
        fwrite(ptinode, sizeof(inode), 1, disk);

        initDiskDirBuff();

        strcpy(PWD, "/");

        printf("\n");
    }

    int op;
    op = 1;
    char t[20];
    while (op != 0) {
        //TODO
//        printf("跟目录信息\n");
        //        showInode(rootDir);

        printf("\n");
        menu();
        printf("\n");
        printf("\n\n输入操作:");
        scanf("%d", &op);

        char pathname[20];
        char write[100];
        inode tnode;
        myFILE*fp;
        switch (op) {
            case 1:
                //TODO
                create_file();
                break;
            case 2:
                //TODO
                //            md(&tnode);
                printf("输入创建的目录\n");
                scanf("%s", pathname);
                
                if(pathname[0]!='/')
                {
                    strcpy(t,PWD);
                    strcat(t,"/");
                    strcat(t,pathname);
                    strcpy(pathname,t);
                }
                
                printf("PWD = %s\n",PWD);
                md(pathname);
                break;
            case 3:
                printf("输入要显示的文件名:\n");
                scanf("%s", pathname);
                
                if(pathname[0]!='/')
                {
                    strcpy(t,PWD);
                    strcat(t,"/");
                    strcat(t,pathname);
                    strcpy(pathname,t);
                }
                typefile(pathname);
                break;
            case 4:

                printf("输入需要删除的文件的路径名\n");
                scanf("%s", pathname);
                if(pathname[0]!='/')
                {
                    strcpy(t,PWD);
                    strcat(t,"/");
                    strcat(t,pathname);
                    strcpy(pathname,t);
                }
                
                delete_file(pathname);
                break;

            case 5:
                printf("输入需要删除的空目录的路径名\n");
                scanf("%s", pathname);
                if(pathname[0]!='/')
                {
                    strcpy(t,PWD);
                    strcat(t,"/");
                    strcat(t,pathname);
                    strcpy(pathname,t);
                }
                
                rd(pathname);
                break;
            case 6:
                printf("输入需要写入的文件\n");
                scanf("%s", pathname);
                if(pathname[0]!='/')
                {
                    strcpy(t,PWD);
                    strcat(t,"/");
                    strcat(t,pathname);
                    strcpy(pathname,t);
                }
                
                fp = open_file(pathname);
                showFile(*fp);
                
                getchar();
                printf("输入写入内容(回车结束)\n");
                gets(write);
                for (i = 0; i < 50; i++) {
                    if(write[i] == 0)
                        break;
                }

//                printf("i=%d",i);
                if (fp != NULL) {
                    fp->writepyl = fp->length;
                    myFwrite(write, sizeof(char), i, fp);
                    break;
                } else {
                    printf("没有这个文件\n");
                    break;
                }
                break;
            case 7:
                printf("输入需要显示的目录列表\n");
                scanf("%s", pathname);
                if(pathname[0]!='/')
                {
                    strcpy(t,PWD);
                    strcat(t,"/");
                    strcat(t,pathname);
                    strcpy(pathname,t);
                }    
                
                showDir(pathname);
                break;
            case 8:
                printf("输入改变的文件\n");
                scanf("%s",pathname);
                
                if(pathname[0]!='/')
                {
                    strcpy(t,PWD);
                    strcat(t,"/");
                    strcat(t,pathname);
                    strcpy(pathname,t);
                }
                change(pathname);
                break;
            case 9:
                showFAT();
             break;
            case 10:
                
                printf("将PWD修改为:");
                scanf("%s",PWD);
                break;
            default:
                //TODO
                break;
        }
    }

    //在关闭磁盘前将FAT缓存中的内容存放在磁盘中
    fseek(disk, 64, SEEK_SET);
    fwrite(FAT, sizeof(int8_t), 128, disk);

    closeDir();
    fclose(disk);
    return 0;

}

void menu() {

    printf("\t\t*************************\n");
    printf("\t\t选择操作:\n");
    printf("\t\t0:退出系统\n");
    printf("\t\t1:创建文件\n");
    printf("\t\t2:创建目录\n");
    printf("\t\t3:输出文件内容\n");
    printf("\t\t4:删除文件\n");
    printf("\t\t5:删除空目录\n");
    printf("\t\t6:追加写入文件\n");
    printf("\t\t7:显示目录\n");
    printf("\t\t8:改变文件属性\n");
    printf("\t\t9:显示FAT\n");
    printf("\t\t10:修改PWD\n");
    printf("\t\t*************************\n");
    
    freeblocknum = 0;
    for (int i = 0; i < 128; i++) {
        if (FAT[i] == 0)
            freeblocknum++;
    }
    printf("\t\t\t磁盘总块数:%d,剩余磁盘块数:%d", 128, freeblocknum);
}

void setPWD(char path[]){
    
    strcpy(PWD,path);
}

void initDiskDirBuff() {
    //初始化目录缓存
    int8_t block[64];

    fseek(disk, 3 * 64, SEEK_SET);
    fread(block, sizeof(int8_t), 64, disk);
    inode *ptinode ;

    ptinode = (inode*)malloc(sizeof(inode));
    strcpy(ptinode->name, "#");
    ptinode->length = 8;
    ptinode->startb = 3;
    ptinode->attribute = attribute_dir;

//    showInode(*ptinode);
    myFILE *rootfp = (myFILE*)malloc(sizeof(myFILE));

    rootfp->readb = 0;
    rootfp->readpyl = 0;
    rootfp->writepyl = 0;
    rootfp->writeb = 0;
    rootfp->startb = 3;
    rootfp->length = 8;
    rootfp->logicB[0] = 3;

//    rootDir = (DirBuff*)malloc(sizeof(DirBuff));
//    rootDir->num = 1;
//    rootDir->DIRI[0] = *ptinode;
//    rootfp->FCBp = &rootDir->DIRI[0];
    rootfp->FCBp = ptinode;

    rootDir = NULL;

//    printf("传递进入的长度为:%d\n", rootfp->length);

    readDir(&rootDir, rootfp);

}

void showInode(inode FCB) {

    char tname[10];
    strcpy(tname, FCB.name);
    strcat(tname, ".");
    strcat(tname, FCB.type);

    printf("%7s", tname);
    printf("%5d", FCB.startb);
    printf("%5dB", FCB.length);

    if (FCB.attribute == attribute_file) {
        printf("%6s", "文件");

    } else if (FCB.attribute == attribute_dir) {
        printf("%6s", "目录");
    } else if (FCB.attribute == attribute_sys) {
        printf("%6s", "系统");
    } else if (FCB.attribute == attribute_onlyr) {
        printf("%6s", "只读文件");
    }

    printf("\n");
//    printf("\nshow结束\n");
}

void showFile(myFILE fp) {

    printf("写指针偏移量:%d,写入的逻辑块:%d,写入的物理块:%d\n", fp.writepyl, fp.writeb, fp.logicB[fp.writeb]);

    printf("读指针偏移量:%d,读入的逻辑块:%d,读入的物理块:%d\n", fp.readpyl, fp.readb, fp.logicB[fp.readb]);

    printf("文件的大小:%d\n", fp.length);
    printf("文件的起始块:%d\n", fp.startb);
}

//1 查文件 2查目录
//find 只能从根目录开始查找 pathname 必须以 '/' 开始
int  find(DirBuff **DirB, int *Index, char pathname[], int mod) {

    //根目录结点

    int i, j;
    i = 0;
    j = 0;

    //拆解目录和文件
    //测试正确 1>
    char dirname[10][3];
    int pnameI = 1;
    if (pathname[0] != '/') {
        printf("路径错误\n");
        return 0;
    }

    while (pathname[pnameI] != 0) {
        //TODO
        //        printf("循环\n");
        j = 0;
        while (pathname[pnameI] != 0 && pathname[pnameI] != '/') {
            //TODO
            dirname[i][j++] = pathname[pnameI++];
        }

        if (j > 2 || j == 0) {
            printf("路径错误\n");
            return 0;
        }

        dirname[i][j] = dirname[i][2] = 0;

        if (pathname[pnameI] == '/') {
            pnameI++;
        }

        i++;

    }
    int n = i;
    //测试正确 1<

    DirBuff *ptnode = rootDir;
    DirBuff *dirt;

    //查找根目录
    if (n == 0) {

        *DirB = rootDir;
        *Index = 0;
        return 1;
    }

    *Index = 0;
    //有n层目录或文件
    //先找其中n-1层的,这一定是目录
    for (i = 0; i < n - 1; i++) {

        printf("**************%s\n", dirname[i]);
        if (ptnode->DIRI[*Index].startb != -1) {
            dirt = ptnode->nextDIR[*Index];
        } else {
            printf("没有找到\n");
            *DirB = rootDir;
            *Index = 0;
            return 0;
        }

        int m;
        m = dirt->num;
//        printf("m=%d\n", m);

        for (j = 0; j < m; j++) {

            inode  tnode = dirt->DIRI[j];

            //找到对应的目录

            if (strcmp(dirname[i], tnode.name) == 0 && tnode.attribute == attribute_dir) {

                //说明还有下一层
//
//                printf("查找过程中遇到的结点\n");
//                showInode(tnode);
                ptnode = dirt;
                *Index = j;
                break;

            }
        }
        if (j == m) {
            printf("没有这个路径\n");
            *DirB = rootDir;
            *Index = 0;
            return 0;
        }

    }

    //
//    showInode(ptnode->DIRI[*Index]);
    if (ptnode->DIRI[*Index].startb != -1) {
        dirt = ptnode->nextDIR[*Index];
    } else {
        printf("没有这个路径\n");
        *DirB = rootDir;
        *Index = 0;
        return 0;
    }

//    printf("dirt->num = %d\n",dirt->num);
    int m = dirt->num;
    for (j = 0; j < m; j++) {

//        showInode(dirt->DIRI[j]);
        if (strcmp(dirt->DIRI[j].name, dirname[n - 1]) == 0) {

            if (mod == 1 && dirt->DIRI[j].attribute == attribute_file) {

                *Index = j;
                break;
            } else if (dirt->DIRI[j].attribute == attribute_dir) {
                *Index = j;
                break;
            } else {
                printf("没有这个路径\n");
                *DirB = rootDir;
                *Index = 0;
                return 0;
            }
        }
    }

    if (j == m) {
        printf("没有这个路径\n");
        *DirB = rootDir;
        *Index = 0;
        return 0;
    }

    ptnode = dirt;
    *Index = j;
    *DirB = ptnode;
    //    printf("find 结束\n");
    //    printf("%d\n",*Index);
    //    showInode(ptnode->DIRI[*Index]);
    return 1;
}

myFILE* open_file(char pathname[]) {

    DirBuff *dirt;
    int Index;

    if (find(&dirt, &Index, pathname, 1) == 0) {
        printf("没有这个文件\n");
        return NULL;
    }

//    showInode(dirt->DIRI[Index]);
    myFILE *fp = (myFILE*)malloc(sizeof(myFILE));
    fp->writeb = 0;
    fp->writepyl = 0;
    fp->readb = 0;
    fp->readpyl = 0;
    fp->length = dirt->DIRI[Index].length;
    fp->FCBp = &dirt->DIRI[Index];
    fp->startb = dirt->DIRI[Index].startb;

    int i = fp->startb;
    if (i == -1) {
        return fp;
    }
    int j = 0;

//    showFile(*fp);
    while (FAT[i] != -1 && j <= fp->length / 64) {
        printf("i = %d\n", FAT[i]);
        fp->logicB[j++] = i;
        i = FAT[i];
    }

    fp->logicB[j] = i;

//    showFile(*fp);
    return fp;

}

size_t myFread(void *ptr, size_t size, size_t n, myFILE *fp) {

//    showFile(*fp);

    char *tptr = (char*)ptr;

    char *block = (char*)malloc(sizeof(int8_t) * 64);

    fseek(disk, fp->logicB[fp->readb] * 64, SEEK_SET);
    fread(block, sizeof(int8_t), 64, disk);

    int i, j;

//    printf("\n读_____________\n");
//    for (i = 0; i < 64; i++) {
//        if (i % 8 == 0)
//            printf("\n");
//        printf("%5d", block[i]);
//    }
//    printf("\n_____________\n");

    for (i = 0; i < (int)n; i++) {

        for (j = 0; j < (int)size; j++) {
            if (fp->readpyl / 64 != fp->readb) {
                fp->readb = fp->readpyl / 64;
                fseek(disk, fp->logicB[fp->readb] * 64, SEEK_SET);
                fread(block, sizeof(int8_t), 64, disk);
            }

            tptr[i * size + j] = block[fp->readpyl % 64];
            fp->readpyl++;
        }

    }

    return i;
}

int delete_file(char pathname[]) {

    DirBuff *dirt;
    int Index;

    if (find(&dirt, &Index, pathname, 1) == 0)
        return 1;

    myFILE *fp;
    fp = open_file(pathname);

    int i = fp->startb;

    //文件有开始的内容
    if (i != -1) {

        while (FAT[i] != -1) {
            FAT[i] = 0;
            i++;
        }
        FAT[i] = 0;
    }

    //从目录中删除

    int j = 0;
    for (i = 0, j = 0; i < dirt->num; ) {

//        printf("Index = %d", Index);

        dirt->DIRI[j] = dirt->DIRI[i];
        dirt->nextDIR[j] = dirt->nextDIR[i];
        if (i != Index) {
            j++;
            i++;
        } else {
            i++;
        }

    }

    dirt->num--;
    return 1;
}

void typefile(char pathname[]) {

    char readb[128];
    myFILE *fp;
    fp = open_file(pathname);
//    printf("type中\n");
//    showFile(*fp);
    if (fp == NULL) {
        printf("文件不存在\n");
        return;
    }
    myFread(readb, sizeof(char), fp->length, fp);

//    showFile(*fp);
    for (int i = 0; i < fp->length; i++) {
        if (i % 8 == 0)
            printf("\n");

        printf("%5c", readb[i]);
    }

    printf("\n");
}

void myFwrite(void *ptr, size_t size, size_t num, myFILE* fp) {

    showFile(*fp);
    char *tptr;
    tptr = (char *)ptr;

    char *block = (char*)malloc(sizeof(int8_t) * 64);

    //文件不为空
    if (fp->startb != -1) {
        fseek(disk, fp->logicB[fp->writeb] * 64, SEEK_SET);
        fread(block, sizeof(int8_t), 64, disk);
    } else {
        int k;
        for (k = 0; k < 128; k++) {
            if (FAT[k] == 0) {
//                fp->logicB[fp->writeb + 1] = k;
//                FAT[fp->logicB[fp->writeb]] = k;
                FAT[k] = -1;
                break;
            }
        }

        if (k == 128) {
            printf("磁盘空间不足\n");
            return;
        } else {
            fp->startb = k;
            fp->FCBp->startb = k;
            fp->logicB[0] = k;
//            showFile(*fp);
        }
        fseek(disk, fp->logicB[fp->writeb] * 64, SEEK_SET);
        fread(block, sizeof(int8_t), 64, disk);
    }
    int i, j;
    
    for (i = 0; i < (int)num; i++) {

        for (j = 0; j < (int)size; j++) {

            //追加写
            //文件超过以前写的内容

//            printf("输入发生\n");
            if (fp->writepyl + 1 > fp->length) {

                //分配给文件的磁盘块用完了,需要新的块
//                printf("\n\n\n***\n文件长度增加\n\n");

                //文件的长度是块的整数倍数了
                //长度再增大需要分配新的块
                if (fp->length % 64 == 0) {
                    int k;
                    for (k = 0; k < 128; k++) {
                        if (FAT[k] == 0) {
                            fp->logicB[fp->writeb + 1] = k;
                            FAT[fp->logicB[fp->writeb]] = k;
                            FAT[k] = -1;
                            break;
                        }
                    }

                    if (k == 128) {
                        printf("磁盘空间不足\n");
                        return;
                    }
                }
//
//                //添加一个字节时候是否超过已经分配块的最大容量
//                if ((fp->writeb + 1) * 64 < (fp->writepyl + 1)) {
//
                    printf("\n\n发生新申请块\n\n");
                    showFAT();
//
//                    int k;
//                    for (k = 0; k < 128; k++) {
//                        if (FAT[k] == 0) {
//                            fp->logicB[fp->writeb + 1] = k;
//                            break;
//                        }
//                    }
//
//                    if (k == 128) {
//                        printf("磁盘空间不足\n");
//                        return;
//                    } else {
//                        FAT[fp->logicB[fp->writeb]] = k;
//                        fp->logicB[fp->writeb+1] = k;
//                    }
//                }

                fp->FCBp->length++;
                fp->length++;
            }
            if ((fp->writepyl) / 64 != fp->writeb) {

                fseek(disk, fp->logicB[fp->writeb] * 64, SEEK_SET);
//                printf("写入\n");
                fwrite(block, sizeof(int8_t), 64, disk);

                fp->writeb = fp->writepyl / 64;
                fseek(disk, fp->logicB[fp->writeb] * 64, SEEK_SET);
                fread(block, sizeof(int8_t), 64, disk);
            }
            block[fp->writepyl % 64] = tptr[i * size + j];
            fp->writepyl++;

//            printf("fp    \n");
//            showFile(*fp);
        }

    }

    fseek(disk, fp->logicB[fp->writeb] * 64, SEEK_SET);
//    printf("\n_____________\n");
//    for (i = 0; i < 64; i++) {
//        if (i % 8 == 0)
//            printf("\n");
//        printf("%5c", block[i]);
//    }
//    printf("\n_____________\n");

    fwrite(block, sizeof(int8_t), 64, disk);
    fseek(disk, fp->logicB[fp->writeb] * 64, SEEK_SET);
    fread(block, sizeof(int8_t), 64, disk);

//    printf("写入的东西读出来后的结构\n");
//    printf("起始块:%d\n", fp->logicB[fp->writeb]);
//    printf("\n>>_____________\n");
//    for (i = 0; i < 64; i++) {
//        if (i % 8 == 0)
//            printf("\n");
//        printf("%5c", block[i]);
//    }
//    printf("\n>>_____________\n");

}

//readDir(rootDir,3,1);

void showFAT() {

    int i;
    for (i = 0; i < 128; i++) {
        if (i % 8 == 0)
            printf("\n");
        printf("%5d", FAT[i]);
    }

    printf("\n");
}

int readDir(DirBuff **root, myFILE *fp) {

//    printf("进入readDir中的长度:%d\n", fp->length);
    *root = (DirBuff*)malloc(sizeof(DirBuff));

    int i, n;
    n = fp->length / 8;

    (*root)->num = n;

    myFread((*root)->DIRI, sizeof(inode), n, fp);

//    printf("||\n%s 的 目录项 %d||\n", fp->FCBp->name, (*root)->num);
    for (i = 0; i < n; i++) {
        (*root)->nextDIR[i] = NULL;
    }

    for (i = 0; i < n; i++) {

//        showInode((*root)->DIRI[i]);
        //目录不为空
        if ((*root)->DIRI[i].startb != -1 && (*root)->DIRI[i].attribute == attribute_dir) {
            myFILE *fpt = (myFILE*)malloc(sizeof(myFILE));
            fpt->readb = 0;
            fpt->readpyl = 0;
            fpt->writepyl = 0;
            fpt->writeb = 0;
            fpt->length = (*root)->DIRI[i].length;
            fpt->startb = (*root)->DIRI[i].startb;
            fpt->FCBp = &(*root)->DIRI[i];
            fpt->logicB[0] = (*root)->DIRI[i].startb;
            readDir(&(*root)->nextDIR[i], fpt);
        }

    }

    return 1;
}

int closeDir() {

    //初始化目录缓存

    inode* ptinode;
    ptinode = &rootDir->DIRI[0];
    myFILE *rootfp = (myFILE*)malloc(sizeof(myFILE));

//    showInode(*ptinode);
    rootfp->readb = 0;
    rootfp->readpyl = 0;
    rootfp->writepyl = 0;
    rootfp->writeb = 0;
    rootfp->startb = 3;
    rootfp->length = 8;
    rootfp->logicB[0] = 3;
    rootfp->FCBp = &rootDir->DIRI[0];

//    showInode(rootDir->DIRI[0]);
    writeDir(rootDir, rootfp);

//    showFAT();
    return 1;
}

int writeDir(DirBuff*root, myFILE*fp) {

    int i;
    myFwrite(root->DIRI, sizeof(inode), root->num, fp);

    for (i = 0; i < root->num; i++) {

        //目录不为空
        if (root->DIRI[i].startb != -1 && root->DIRI[i].attribute == attribute_dir) {

            myFILE *fpt = (myFILE*)malloc(sizeof(myFILE));
            fpt->writeb = 0;
            fpt->writepyl = 0;
            fpt->readb = 0;
            fpt->readpyl = 0;
            fpt->length = root->DIRI[i].length;
            fpt->startb = root->DIRI[i].startb;
            fpt->FCBp = &root->DIRI[i];

            //现在假设的目录最多8项
            fpt->logicB[0] = root->DIRI[i].startb;
            writeDir(root->nextDIR[i], fpt);
        }

    }

    return 1;
}

int create_file() {

    int i;
    char path[20];
    printf("输入路径名:");
    scanf("%s", path);
    printf("路径为:%s\n", path);

    path[19] = 0;

    if (path[0] == '/') {
//        printf("查找绝对路径\n");
    } else {

//        printf("相对路径\n");
        char tpath[20];
        strcpy(tpath, path);
        strcpy(path, PWD);
        strcat(path,"/");
        strcat(path, tpath);
    }

    printf("path = %s\n",path);

    //始终保存path中存的是绝对路径

    DirBuff *dirt;
    int Index;
    if (find(&dirt, &Index, path, 2) == 0) {
        printf("没有这个路径\n");
        return 0;
    }

//    showInode(dirt->DIRI[Index]);

    if (dirt->DIRI[Index].startb == -1) {

        dirt->nextDIR[Index] = (DirBuff*)malloc(sizeof(DirBuff));

        for (i = 0; i < 128; i++) {
            if (FAT[i] == 0)
                break;
        }

        if (i >= 128) {
            printf("没有空闲磁盘,不能创建文件\n");
            return 0;
        } else {
            FAT[i] = -1;
            dirt->DIRI[Index].startb = i;
            dirt->nextDIR[Index]->num = 0;
        }

    }

    printf("输入文件名:");
    char filename[3];

    scanf("%s", filename);
    filename[2] = 0;

//    printf("创建的文件为:%s\n", filename);
//
//    printf("找到的目录的记录数:%d\n", dirt->nextDIR[Index]->num);

    for (i = 0; i < dirt->nextDIR[Index]->num; i++) {

        inode t = dirt->nextDIR[Index]->DIRI[i];

//        printf("这个文件: %s\n", t.name);

        if (strcmp(t.name, filename) == 0 && t.attribute == attribute_file) {
            printf("此文件已经存在\n");
            return 0;
        }
    }

    inode tfile;
    //文件信息初始化
    tfile.length = 0;
    tfile.startb = -1;
    strcpy(tfile.name, filename);
    tfile.attribute = attribute_file;
    strcpy(tfile.type, "b");

    dirt->DIRI[Index].length += 8;
    i = dirt->nextDIR[Index]->num;
    dirt->nextDIR[Index]->DIRI[i] = tfile;
    dirt->nextDIR[Index]->num++;

    printf("\n新创建的文件是\n");
    printf("*******\n");
    showInode(tfile);
    printf("*******\n\n");
    return 1;
}

int md(char pathname[]) {

    if (pathname[0] != '/') {
        char tname[20];
        strcpy(tname, pathname);
        strcpy(pathname, PWD);
        strcat(pathname, tname);
    }

    //拆解目录和文件
    //测试正确 1>
    char dirname[10][3];
    int pnameI = 1;
    int i, j;

    if (pathname[0] != '/') {
        printf("路径错误\n");
        return 0;
    }
    while (pathname[pnameI] != 0) {
        //TODO
        //        printf("循环\n");
        j = 0;
        while (pathname[pnameI] != 0 && pathname[pnameI] != '/') {
            //TODO
            dirname[i][j++] = pathname[pnameI++];
        }

        if (j > 2 || j == 0) {
            printf("路径错误\n");
            return 0;
        }

        dirname[i][j] = dirname[i][2] = 0;

        if (pathname[pnameI] == '/') {
            pnameI++;
        }

        i++;

    }
    int n = i;
    //测试正确 1<

    DirBuff *pdirt = rootDir;
    int Index = 0;
    DirBuff *dirt = rootDir->nextDIR[0];
//    printf("从根处开始找\n");
    for (i = 0; i < n; i++) {
        int m = dirt->num;
        for (j = 0; j < m; j++) {

            if (strcmp(dirt->DIRI[j].name, dirname[i]) == 0 && dirt->DIRI[j].attribute == attribute_dir) {

                showInode(dirt->DIRI[j]);
                pdirt = dirt;
                Index = j;

                if (dirt->DIRI[j].startb != -1) {
                    dirt = dirt->nextDIR[j];
                    break;
                } else {

                    for (j = 0; j < 128; j++) {
                        if (FAT[j] == 0)
                            break;
                    }

                    if (j == 128) {
                        printf("磁盘空间不够\n");
                        return 0;
                    }

                    else {
                        FAT[j] = -1;
                        dirt->DIRI[j].startb = j;
                    }

                    dirt->nextDIR[j] = (DirBuff*)malloc(sizeof(DirBuff));
                    dirt->nextDIR[j]->num = 0;

                    dirt = dirt->nextDIR[j];
                }

            }
        }

        //没有找到
        if (j == m) {
            break;
        }
    }

    inode tinode;

//    printf("*****************************************\n");
    for (; i < n; i++) {

        tinode.attribute = attribute_dir;
        strcpy(tinode.name, dirname[i]);
        strcpy(tinode.type, "d");
        int m = dirt->num;
//        printf("i=%d,m=%d",i,m);

        dirt->num++;
        pdirt->DIRI[Index].length += 8;

        //将新结点添加进去
        if (i != n - 1) {

            tinode.length = 0;
            for (j = 0; j < 128; j++) {
                if (FAT[j] == 0)
                    break;
            }

            if (j == 128) {
                printf("磁盘空间不够\n");
                return 0;
            }

            else {
                FAT[j] = -1;
                tinode.startb = j;
            }

            dirt->DIRI[m] = tinode;

            printf("\n新建的文件的信息\n");
            showInode(tinode);

            dirt->nextDIR[m] = (DirBuff*)malloc(sizeof(DirBuff));
            dirt->nextDIR[m]->num = 0;

            pdirt = dirt;
            Index = m;
            dirt = dirt->nextDIR[m];

        } else {

            tinode.length = 0;

            tinode.startb = -1;

            dirt->DIRI[m] = tinode;
            dirt->nextDIR[m] = NULL;
        }

    }

    return 1;
}

void change(char pathname[]){
    
    DirBuff *dirt;
    int Index;
    
    if(find(&dirt,&Index,pathname,1)==0){
        return;
    }
    printf("选择文件属性修改为:\n");
    printf("1:只读\n");
    printf("2:普通\n");
    printf("3:系统文件\n");
    
    int op;
    scanf("%d",&op);
    if(op ==1){
        dirt->DIRI[Index].attribute = attribute_onlyr;
    }else if(op == 2){
        dirt->DIRI[Index].attribute = attribute_file;
    }else if(op==3){
        dirt->DIRI[Index].attribute = attribute_sys;
    }
    
}

void rd(char pathname[]) {

    DirBuff *dirt;
    int Index;

    if (find(&dirt, &Index, pathname, 2) == 0) {
        return;
    }

    if (dirt->DIRI[Index].startb != -1 && dirt->DIRI[Index].attribute == attribute_dir) {
        printf("不是空目录,不能删除");
        return;
    }

    int i = dirt->DIRI[Index].startb;

    //文件有开始的内容
    if (i != -1) {

        while (FAT[i] != -1) {
            FAT[i] = 0;
            i++;
        }
        FAT[i] = 0;
    }

    //从目录中删除

    int j = 0;
    for (i = 0, j = 0; i < dirt->num; ) {

//        printf("Index = %d", Index);

        dirt->DIRI[j] = dirt->DIRI[i];
        dirt->nextDIR[j] = dirt->nextDIR[i];
        if (i != Index) {
            j++;
            i++;
        } else {
            i++;
        }

    }

    dirt->num--;
}

void showDir(char path[]) {

    DirBuff *tDir;
    int Index;

    if (find(&tDir, &Index, path, 2) == 0) {
        printf("没有找到目录\n");
        return;
    }

    if (tDir->DIRI[Index].startb == -1) {
        printf("空目录\n");
        return;
    }

    DirBuff *dirc = tDir->nextDIR[Index];

    for (int i = 0; i < dirc->num; i++) {
        showInode(dirc->DIRI[i]);
    }

}

本文转载自: https://blog.csdn.net/qq_52268656/article/details/130201069
版权归原作者 奇迹師 所有, 如有侵权,请联系我们删除。

“使用C语言实现磁盘的文件管理系统”的评论:

还没有评论