📄 file_manage.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 + -