⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file_manage.c

📁 一个简单的文件系统摸拟,提供给大家学习和交流
💻 C
字号:
/* 
 * 文件管理实验程序完整版 1.2.1
 * 把一个文件模拟为磁盘,然后在该磁盘上建立文件系统,
 * 并提供基本的文件访问函数
 * 作者:何杉
 * 最后修改时间:2005-4-13 16:05
 */

#include <stdio.h>
#include <string.h>

/*************** 可以使用的函数和宏 ********************/

#define SECTOR_SIZE     256     /* 每个扇区的大小 */
#define TOTAL_SECTOR    128     /* 扇区总数 */

struct node
{
    char filename[20];
    char index;
    int  filesize;
};
/* 把磁盘的第sector个扇区内容读入到buf
   sector从0开始编号
   运行正确返回非0值,错误返回0 */
int read_disk(int sector, void* buf);

/* 把buf中SECTOR_SIZE个字节的数据写到磁盘的第sector个扇区
   sector从0开始编号
   运行正确返回非0值,错误返回0 */
int write_disk(int sector, void* buf);

/*************** 可以使用的函数和宏结束 *****************/

/* 所有与文件系统有关的初始化工作都在此完成
   成功返回非0值,否则返回0 */
int init_fs(void)
{
    int i;
    char FAT[128];                   /*以128B大小为block*/
    struct node dir[128];
    read_disk(0, FAT);
    read_disk(1, dir);     /*检查磁盘0号扇区是否为空,为空则需格式化磁盘*/
    if(strcmp(FAT, 0) == 0)
    {
        FAT[TOTAL_SECTOR] = -1;
        for(i=0;i<128;i++)   /*将文件初始化*/
        {
            dir[i].filename[20] = 0;
            dir[i].index = 0;
            dir[i].filesize=0;
        }
    }
    write_disk(0, FAT);    /*将FAT表写到0号扇区*/
    write_disk(1, dir);    /*将索引表写到1号扇区*/

    return !0;
}

/* 从文件filename的头部开始读size大小的内容到buf
   如果文件实际内容不够size,就有多少读多少
   返回实际读入的字节数。如果出错,返回0 */
int my_read(const char* filename, void* buf,int size)
{
    int tsize;                  /*定义tsize用来读出每个文件中实际存在的字节数目*/
    int i = 0;                  /*文件只能从第二个扇区开始存放*/
    struct node dir[128];      /*将索引表的长度定为128个字节*/
    read_disk(1, dir);          /*将索引表写入扇区1 */
     printf("%s\n",dir[0].filename);
    while(strcmp(dir[i].filename, filename) != 0)  /*根据文件名字查找所需文件*/
     i++;
     read_disk(i, buf);
    return strlen(buf);     /*返回读入数据的个数一字节为单位*/

}

/* 把buf指向的size大小的内容写入到文件filename
   如果文件不存在,就新建。存在,就覆盖
   成功返回非0值,否则返回0 */
int my_write(const char* filename, void* buf, int size)
{
    int i=2;
    int j=0;
    char* buffer = (char*) buf;
    int blocks = size/256;      /*将每个扇区定义为一个block并将其转换为整形*/
    char FAT[128];
    struct node dir[128];

    read_disk(0, FAT);
    read_disk(1, dir);          /*将dir目录写入扇区1*/

          /*若dir[i]的文件名不等于0,就接着往下找*/
    while(strcmp(dir[i].filename, 0) != 0)
        /*判断要写的文件是不是跟已存在的文件重名*/
    {
        if(strcmp(dir[i].filename, filename) == 0)
            break;
        i++;
    }
    /*说明此时要写的文件确定跟已存在的文件重名*/
    if(strcmp(dir[i].filename, filename) == 0)
    {
        /*把buf后面大于size的部分截去*/
        for(j=size;j<strlen(buffer);j++)
            buffer[j] = 0;
        write_disk(i, buffer);
       dir[i].index = i;    /*将文件的索引记录为的i个扇区的扇区号*/
        write_disk(1,dir);
    }
    else           /*如果此时的文件为新创立的文件*/
    {
        strcpy(dir[i].filename, filename);

        write_disk(i, buffer);
        dir[i].index = i;
        write_disk(1,dir);

    }

    if(blocks>1)
    {
        for(;j<blocks;j++)
        {
            write_disk(i, buf);
            FAT[i] = i+1;
        }
        write_disk(0, FAT);
        write_disk(1, dir);
    }

    return !0;
}



/************************************************
 * 下面为main要使用的内容,不要修改,也不需考虑 *
 * 专心完成上面函数的功能即可                   *
 * 然后运行程序进行测试                         *
 ************************************************/
int write_file(void);
int read_file(void);
int get_filename(char* filename);
int get_file_content(char* buf);
int init_disk(void);
void close_disk(void);

#define MAX_FINENAME_LEN    20
#define MAX_BUF_LEN         4*SECTOR_SIZE

int main(void)
{
    int ch = 0;
    int rtn = 1;
    
    if (!init_disk())
    {
        perror("vdisk.dat");
        return -1;
    }

    if (!init_fs())
    {
        printf("init_fs() error!\n");
        return -2;
    }

    do
    {
        switch (ch)
        {
        case 'w':
            getchar();
            rtn = write_file();
            break;
        case 'r':
            getchar();
            rtn = read_file();
            break;
        case '\n':
            continue;
        }
        if (!rtn)
            printf("\nError!!!!\n");
        printf("\nInput \'w\' to write, \'r\' to read and \'q\' to quit:");

    } while ((ch=getchar()) != 'q');

    close_disk();
    return 0;
}

int write_file(void)
{
    char filename[MAX_FINENAME_LEN];
    char buf[MAX_BUF_LEN];
    int rtn=0;

    if(get_filename(filename))
    {
        int n = get_file_content(buf);
        rtn = my_write(filename, buf, n);
    }
    else
    {
        rtn = 0;
    }

    return rtn;
}

int read_file(void)
{
    char filename[MAX_FINENAME_LEN];
    char buf[MAX_BUF_LEN];
    int rtn=0;

    if(get_filename(filename))
    {
        int i;

        rtn = my_read(filename, buf, MAX_BUF_LEN);
        for (i=0; i<rtn; i++)
            putchar(buf[i]);
    }
    else
    {
        rtn = 0;
    }

    return rtn;
}

int get_filename(char* filename)
{
    int len;
    
    printf("Enter filename:");
    fgets(filename, MAX_FINENAME_LEN, stdin);
    len = strlen(filename);
    
    if (filename[len-1] == '\n')
    {
        filename[len-1] = '\0';
        len--;
    }
    return len;
}

int get_file_content(char* buf)
{
    int ch, count=0;

    printf("Input file content. Input '~' to end.\n");

    while ((ch = getchar()) != '~')
    {
        buf[count] = ch;
        count++;
    }

    return count;
}

FILE* disk = NULL;

int init_disk(void)
{
    char dump[SECTOR_SIZE] = {0};
    int count=0;

    while (disk == NULL && count < 4)
    {
        disk = fopen("vdisk.dat", "r+b");
        count++;
        if (disk == NULL) /* 虚拟文件不存在,建立 */
        {
            int i;
            disk = fopen("vdisk.dat", "wb");
            if (disk == NULL)
                return 0;
            for (i=0; i<TOTAL_SECTOR; i++)
                fwrite(dump, SECTOR_SIZE, sizeof(char), disk);
            fclose(disk);
            disk = NULL;
        }
    }

    return (int)disk;
}

void close_disk(void)
{
    fclose(disk);
}

int read_disk(int sector, void* buf)
{
    if (!init_disk())
        return 0;

    fseek(disk, sector*SECTOR_SIZE, SEEK_SET);
    return fread(buf, SECTOR_SIZE, 1, disk);
}

int write_disk(int sector, void* buf)
{
    if (!init_disk())
        return 0;

    fseek(disk, sector*SECTOR_SIZE, SEEK_SET);
    return fwrite(buf, SECTOR_SIZE, 1, disk);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -