| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 464 人关注过本帖
标题:[求助]请问【模拟真实磁盘】如何做?
只看楼主 加入收藏
nagen
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2006-7-5
收藏
 问题点数:0 回复次数:0 
[求助]请问【模拟真实磁盘】如何做?

已在磁盘上划分一定空间文件filesys.dat来模拟真实磁盘,现在要在该模拟磁盘中建立文件creatfile(),删除文件del(),创建目录md(),删除目录rd(),文件修改内容并保存edit(),上下级目录访问cd(),cd..(),cd\(),文件复制copy(),这些函数怎么写啊?请大家帮帮忙!写好后可发到邮箱jsj5219@163.com

部分代码:

#include "stdio.h"
#include "conio.h"

struct filesys_superblk
{ /*文件系统的分区信息,存放在0#物理块中*/
unsigned long fs_size; /*整个分区的总磁盘物理块数 */
unsigned long fs_freesize; /*分区的所有空闲磁盘物理块数 */
unsigned int fs_blocksize; /*文件系统的物理块大小(字节)*/
unsigned int fs_fat_start; /*FAT的起始磁盘物理块号 */
unsigned int fs_fat_size; /*FAT占用的磁盘物理块数*/
unsigned int fs_dir_start; /*根目录的起始磁盘物理块号*/
unsigned int fs_dir_size; /*根目录占用的磁盘物理块数*/
unsigned int fs_data_start; /*数据区起始磁盘物理块号*/
unsigned long fs_data_size; /*数据区的磁盘物理块数*/
};


struct FILE_FCB
{ /*文件控制块结构 */
char f_name[16]; /*文件名(16B)*/
short f_mode; /*文件属性,-1表示未用 0表示目录 1表示文件*/
unsigned int f_asize; /*文件分配的大小(物理块数)*/
unsigned long f_rize; /*文件占用的实际大小(字节)*/
unsigned long f_addr; /*文件分配的第一个物理块的块号*/
unsigned int f_ctime; /*文件创建时间*/
unsigned int f_mtime; /*文件修改时间*/
};

struct open_file
{ /*当前正在操作文件的几个FCB数据项 */
char f_name[12] ; /*文件名(16B) */
unsigned int f_asize; /*文件分配的大小(物理块数)*/
unsigned long f_rize; /*文件占用的实际大小(字节)*/
unsigned long f_addr; /*文件分配的第一个物理块的块号*/
};

FILE *filesystem_p; /* 文件系统分区对应的磁盘文件指针,系统运行后文件一直打开,退出系统时关闭文件,所有的模拟文件系统操作都在此文件上进行。*/
static struct filesys_superblk DiskInfo;/*文件系统的管理信息,系统运行时一直存放在内存,提供文件系统操作的参数;*/
static struct FILE_FCB filedir[16]; /*临时存放读取的文件目录,大小可以自己决定,但至少能够存储一个物理块的信息,这里设置的是存储一个物理块的目录项(实际的计算为:fs_blocksize/sizeof(struct FILE_FCB),这里是512/32=16,所以设置数组大小为16,也可以设为32,48,64等),在进行建立文件/目录、删除文件/目录、显示文件/目录、复制等文件操作时,都首先将当前读出的目录信息放到这里,然后进行处理,处理完成后再读取后面的信息再进行处理,为简化处理,自己也可以把数组设置的比较大或采用动态链表的方式存储读出的目录信息。*/
static long fat[128]; /* 存放读入内存的FAT表信息,这里仅设置读取一个物理块的FAT数据,自己可以设置的大一些,在进行许多文件操作时都设计FAT的操作,设置小的时候可能要多次读取FAT区,大的时候少一些,也可以采用动态内存分配的方式,在系统启动时将整个FAT全部装入内存(FAT项数的计算公式为:fs_fat_size*256)。FAT的值定义如下:0为链的结束,-1为未使用,其它正值为链指针,这里未表示出坏的物理块,可以自己根据需要添加。*/
static struct open_file sysopen_file; /* 系统打开文件数据结构,理论上应该是数组 */
static char ReadBuffer[512]; /*读数据缓冲区;用于读磁盘数据时的数据存储 */
static char WriteBuffer[512]; /*写数据缓冲区;用于写磁盘数据时的数据存储*/


/*分区的管理信息到内存DiskInfo结构, 管理信息在格式化时存储到FilesysInfo.dat 开始位置,即0#物理块的开始处*/

void read_fs_superinfo()
{ /*首先定位到文件开始处,然后直接读取 */
rewind(filesystem_p);
fread(&DiskInfo,sizeof(struct filesys_superblk),1, filesystem_p);
return;
}

/*建立文件系统对应的分区文件FilesysInfo.dat,其中要求指出分区大小和物理块大小,也可以为简单起见,大小设置为512B,这里2个都要指出 */

void create_fs_sector()
{ /* 首先输入分区大小(单位是KB)和块大小(单位是B),然后计算需要向
分区文件FilesysInfo.dat里写入的数据块数,执行写操作;数据块数的计公式为:物理块数=分区大小/块大小 */
int i;
unsigned long disksize;
unsigned int blocksize;
unsigned long blknumber;
long blkbuffer[256]; /* 1KB大小的缓冲区 */

for(i=0;i<256;i++) blkbuffer[i]=0; /* 缓冲区赋0值 */

printf("\n please input size of disk: "); /*输入分区大小*/
scanf("%lu", &disksize);

printf("\n please input size of block: "); /*输入物理块大小 如果固定大小512B则不需要输入*/
scanf("%u", & blocksize);

rewind(filesystem_p);
for(i=0;i<disksize;i++)
fwrite(blkbuffer,1024,1,filesystem_p); /* 向文件FilesysInfo.dat里写入的数据,建立disksize KB 大小的分区*/

blknumber=( disksize*1024)/ blocksize ; /*计算整个分区的总物理块数 */
DiskInfo.fs_size= blknumber; /*设置分区信息*/
DiskInfo.fs_freesize =blknumber;
DiskInfo.fs_blocksize= blocksize;

/* 更新磁盘分区信息到 FilesysInfo.dat*/

rewind(filesystem_p);
fwrite(&DiskInfo,sizeof(struct filesys_superblk),1, filesystem_p);
return;
}

void format_fs_sector()
{ /* 通过分区大小和物理块大小计算出总物理块数,由此确定需要FAT的项数,进而计算出FAT区的大小(物理块数),最后填写DiskInfo数据结构,并写回FilesysInfo.dat文件,在本例中,根目录128项,FCB占32B,所以根目录区大小为128*32B ;另外,0#物理块作为管理信息块,所以实际能够分配的物理块从1#开始 */
long temp,i;
unsigned int dirsize;
unsigned int fatsize;
unsigned long blknumber;

/*系统总物理块数*/
blknumber =DiskInfo.fs_size;

/*计算FAT需要占用的物理块数 */
fatsize= (blknumber*4)/DiskInfo.fs_blocksize + 1;

/*计算根目录需要占用的物理块数 */
dirsize= 128*32/DiskInfo.fs_blocksize;

/*重新设置分区的管理信息结构*/
DiskInfo.fs_freesize= blknumber- fatsize - dirsize - 1; /*总空闲物理块数*/

DiskInfo.fs_fat_start =1; /*FAT的起始磁盘物理块号*/
DiskInfo.fs_fat_size=fatsize; /*FAT占用的磁盘物理块数*/

DiskInfo.fs_dir_start=fatsize+1; /*根目录的起始物理块号*/
DiskInfo.fs_dir_size=dirsize; /*根目录占用的物理块数*/

DiskInfo.fs_data_start=fatsize+dirsize+1;/*数据区起始磁盘物理块号*/
DiskInfo.fs_data_size= blknumber- fatsize - dirsize-1; /*数据区的磁盘物理块数*/

/* 格式化FAT, 直接写-1*/

temp=-1;
fseek(filesystem_p,DiskInfo.fs_blocksize,0); /* 定位到1#*/
for(i=0;i<fatsize*128;i++)
fwrite(&temp,4,1,filesystem_p);

/* 格式化DIR区, 属性值为-1*/

filedir[0].f_mode=-1;
fseek(filesystem_p,DiskInfo.fs_dir_start*DiskInfo.fs_blocksize,0); /* 定位*/
for(i=0;i<dirsize*16;i++)
fwrite(&filedir[0],32,1,filesystem_p);


/* 更新磁盘分区信息到 FilesysInfo.dat*/
rewind(filesystem_p);/* 定位到文件开始处*/
fwrite(&DiskInfo,sizeof(struct filesys_superblk),1, filesystem_p);

return;

}


void filesys_init()
{ if((filesystem_p =fopen("Filesys.dat","rb+"))==NULL) /*文件存在?*/
{
/*不存在,建立模拟文件系统的数据文件FilesysInfo.dat*/
if((filesystem_p =fopen("Filesys.dat","wb+"))==NULL)
{ /*不能建立数据文件FilesysInfo.dat,结束程序*/
printf("\nerror on open Filesys.dat!");getch();exit(1);
}

/*能建立数据文件Filesys.dat,则由分区大小和物理块大小真正建立文件系统分区*/
create_fs_sector(); /*建立文件系统分区*/
format_fs_sector();/*格式化文件系统分区*/
}
read_fs_superinfo();/*取文件系统分区的管理信息到内存的DiskInfo中;*/
}


/* 读物理块到缓冲区 */
read_block(long num, char *buf)
{
fseek(filesystem_p,num*DiskInfo.fs_blocksize,0); /* 定位num号物理块到在文件中的位置*/
fread(&buf, DiskInfo.fs_blocksize ,1, filesystem_p); /* 读物理块到内存缓冲区*/
}

/* 写缓冲区数据到物理块 */
write_block(long num, char *buf)
{
fseek(filesystem_p,num*DiskInfo.fs_blocksize,0); /*定位num号物理块到在文件中的位置*/
fwrite(&buf, DiskInfo.fs_blocksize ,1 , filesystem_p); /* 写内存缓冲区到物理块*/
}

main()
{
filesys_init();


}

搜索更多相关主题的帖子: 模拟 磁盘 
2006-07-05 19:27
快速回复:[求助]请问【模拟真实磁盘】如何做?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.035218 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved