资源描述
. . .
课 程 设 计 报 告
课程名称 数据库原理课程设计
课题名称 高校科研管理系统
专 业 计算机科学与技术
班 级 计算机0781
学 号 9
姓 名 熊材盛
指导教师 华光 谭小兰
2010年3月1-13日
工程学院
课 程 设 计 任 务 书
课程名称 数据库原理课程设计
课 题 高校科研管理系统
专业班级 计算机0781
学生 熊材盛
学 号 9
指导老师 周铁山
审 批
任务书下达日期 2009 年 12 月 20 日
任务完成日期 2010 年 3 月 14 日
一、 课程设计的性质和目的
操作系统课程设计是计算机专业的专业课程,通过课程设计使学生进一步巩固课堂所学知识,全面熟悉、掌握操作系统的基本设计方法和技巧,进一步提高分析问题、解决问题与上机操作能力,为将来从事计算机工作打下一定的专业基础。
二、 设计课题
模拟实现单级目录、单级索引的索引文件系统
基本思路:使用域将同一文件的各索引块按顺序连接起来。
基本设计要求:1、实现如下文件系统功能(过程或函数):
a、 打开文件系统 FILE *OPENSYS(char *filename);
b、 关闭文件系统 int CLOSESYS(FILE *stream);
c、 显示目录 void LISTDIR(void);
d、 建立文件 int FCREATE(char *filename);
e、 删除文件 int FDELETE(char *filename);
f、 打开文件 int FOPEN(char *filename);
g、 关闭文件int FCLOSE(int fileid);
h、 文件块读 intFREAD(void *ptr, int n, int fileid);
i、 文件块写 intFWRITE(void *ptr, int n, int fileid);
j、 判断文件结束 int FEOF(int fileid);
k、 获取文件指针 longFGETPOS(int fileid);
l、 设置文件指针 int FSETPOS(int fileid, long offset);
m、 取得文件长度 long FGETLEN(char *filename);
2、提供文件系统创建程序
3、有功能检测模块
4、为简化程序设计,假定目录区域大小固定。
文件系统空间划分:
保留扇区
FAT表区
(或字节映像图区)
根目录区
文件分区
可以使用的C语言文件操纵函数:
FILE *fopen(const char *filename, const char *mode);
int fclose(FILE *stream);
int fseek(FILE *stream, long offset, int whence);
long ftell(FILE *stream);
size_t fread(void *ptr, size_t size, size_t n, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t n, FILE *stream);
三、 课程设计报告要求
1、 设计报告要求A4纸打印成册;
2、 使用学院统一的封面;
3、 课程设计报告每人一份,必须包含如下几个方面的容:
1) 基本设计思想;
2) 主要数据结构;
3) 主要实施流程;
4) 所有源代码;
5) 课程设计总结与体会。
四、 分组与选题办法
1、 按学号顺序一人一组,学号为奇数者为课题一,偶数者为课题二。
2、 成绩考核按个人课题完成情况、设计报告质量与对课程设计的态度等综合评定。
五、设计进度安排
1、 讲课与上机调试时间安排:
上课时间: 未定
上机时间:
2、 其余时间:查阅资料,确定方案,设计课题相关程序。
3、 个人答辩,交课程设计报告。
附:
课程设计报告装订顺序:封面、任务书、目录、正文、评分、附件(A4大小的图纸与程序清单)。
正文的格式:一级标题用3号黑体,二级标题用四号宋体加粗,正文用小四号宋体;行距为22。
正文的容:一、课题的主要功能;二、课题的功能模块的划分(要求画出模块图);三、主要功能的实现(至少要有一个主要模块的流程图);四、程序调试;五、总结;六、附件(所有程序的原代码,要求对程序写出必要的注释)。
正文总字数要求在5000字以上(不含程序原代码)。
目录
一 准备知识…………………………………………………..1
1、目录管理............................................1
2、可能用到的编程技术..................................2
3、用存模拟外存......................................3
二 文件系统的数据结构…………………………………..…3
三 程序设计思想……………………………………………..4
1、程序流程............................................4
2、文件系统的设计思想..................................5
四 几个重要算法……………………………………………..5
五 程序说明………………………………………………..…7
1、源文件的简要说明....................................7
2、程序操作界面........................................7
六 参考文献…………………………………………………..7
评分…………………………………………………………....8
附件………………………………………………………..…..9
一 准备知识
1、目录管理
(1)管理结构
在现代计算机系统中,一般需要存储大量的文件。为了能有效的管理这些文件,必须对它们加以妥善的组织,以便做到用户只需要向系统提供所要访问的文件的名字,就能够快速、准确地找到指定文件。目录管理涉与到文件控制块(File Control Block)和索引节点,目录管理可以分为单级目录结构、两级目录结构和树型目录结构。
文件控制块通常包含:基本信息、存取控制信息和使用信息三部分。
索引节:在文件目录中的每个目录项由文件名以与指向该文件所对应inode的指针所共同构成。
单级目录结构是最简单的目录结果。整个系统当中只建立一目录表,为系统中每一个文件分配一个目录项。本课设使用的是单击目录结构。
在单级目录结果的基础上,为每个用户建立一个单独的用户文件目录UFD(User File Directory),此外在系统中再建立一个主文件目录MFD(Master File Directory),里面放有每个用户的目录项;该目录项中包含也难用户名和指向该用户目录的指针。如下图
Hello.c
1.asm
a.o
用户名
指向子目录的指针
Bill
Stephen
……
……
Happy.c
Work.gz
……
(2)两级目录结构
树型目录机构:在两级目录结果中,再进一步允许用户创建自己的子目录,组织自己的文件,形成三级或者三级以上的文件目录结构,这就被称作树型目录结构。
(3)文件系统的接口
文件系统作为一个高效管理文件的程序,其运行更多的是在系统部进行,而用户所需要关心的只是它的接口。文件系统通常向用户提供两种接口;
命令接口:这是用户与文件系统之间进行交互的接口。用户可以通过键盘终端键入命令来实现与文件系统的交互。
程序接口:这是用户程序与文件系统之间的接口,用户程序可以通过系统调用取得系统文件的服务,完成自己需要的功能。
(4)Fat文件系统
见任务书
2、可能用到的编程技术
(1)Fopen:打开文件
格式:FILE *fopen(const char *filename,const char *mode)
需要头文件stdio.h
filename:待打开的文件名,如果不存在就创建该文件。
mode:打开方式,常用的有
“w”写方式打开,文件不存在就被创建,否则清除原来的容;
“r”读写方式打开,文件必须存在;
“a”添加方式打开;
“w+”读写方式打开,有清除功能;
“r+”读写方式打开,文件必须存在;
“a+”
“t”TEXT方式打开;
“b”二进制方式打开
(2)fwhite和fread:读写文件
size_t fwite(const void *buffer,size_t size,size_t count,FILE *stream);
size_t fread(void *buffer,size_t size,size_t count,FILE *stream);
buffer:待读写的容;
size:一次读写量;
count:需读写buffer的次数;
stream:打开文件的指针
(3)fseek:定位文件
int fseek(FILE *stream,long offset,int origin);
stream:文件指针;
offset:偏移量;
origin:初始位置,有三个常量,SEEL_CUR是当前位置,SEEK_SET文件开头,SEEK_END文件尾。
3、用存模拟外存
真正的文件系统在对外存进行管理时,会涉与到许多有关硬件、设备管理方面的底层技术。一方面这些技术不属于操作系统核心容,另一方面过的容容易造成实验者顾此失彼。所以在这里我们推荐一种使用存来模拟外存的方式,这样就可以跳过这些硬件技术而把精力直接放在数据结构设计和操作算法实现上面。
假定pInode是一个指向inode结构指针,而且它已经放入了需要的数值,现在需要将其写入到特定位置。可用如下代码实现:
……
fd=fopen(“filesystem”,”w+b”); //fd是FILE指针类型,w写方式,b表二进制
fseek(fd,specific_area,SEEK_SET); //fd是文件指针;specific_area为整形
fwrite(pInode,1,sizeof(inode),fd); //写入pInode信息
……
二 文件系统的数据结构
1) 常量
#define BlockSize 512
#define DirSize 32
2) 保留扇区结构
struct ReserveBlock{
int sysblocknum; /*文件系统总扇区数*/
int resblocknum; /*保留扇区扇区数*/
int mapblocknum; /*字节映像图扇区数*/
int rootblocknum; /*根目录区扇区数*/
char fillchar[BlockSize-4*sizeof(int)]; /*填充字节*/
};
3) 目录结构
struct DirBlock{
char filename[11]; /*文件名限长11个字符*/
char fillchar[DirSize-4*sizeof(int)-sizeof(long int)-11]; /*填充字节*/
long filelen; /*文件长度*/
int year,month,day; /*日期*/
int firstindexaddr; /*文件首索引块扇区号*/
};
4) 索引块结构
struct IndexBlock{
int dataaddr[BlockSize/sizeof(int)-1];/*数据块块号数组*/
int nextindexaddr;/*本文件下一索引块块号*/
};
5) 索引节点结构
struct IndexNode{
struct IndexBlock block; /*索引块数据*/
int blockaddr; /*本节点索引块块号*/
struct IndexNode *nextnode; /*指向下一索引节点的指针*/
};
6) FCB(文件控制块)结构
struct FCBBlock{
int fileid; /*文件标识*/
struct DirBlock fileinfo; /*目录信息*/
long filepos; /*文件读写指针*/
int fdtblockaddr; /*目录项所在块号*/
int fdtblockindex; /*目录项所在块序号*/
struct FCBBlock *next; /*指向下一个文件控制块的指针*/
struct IndexNode *firstindexnode; /*指向第一个索引节点的指针*/
};
三 程序设计思想
1、程序流程
这是个面向过程的程序,它的流程图如图所示:
j=sys.resblocknum+sys.fatblocknum;
i++
i<sys.fatblocknum
i=0
memset(&fillchar,0,BlockSize);
i++
i<j
i=0
structReserveBlocksys;
main函数流程图
main函数参考程序:见附录 代码17
2、文件系统的设计思想
真正的文件系统,在涉与到文件读写、文件创建等操作时,会用到外存之间的通信的语句。这些与底层硬件有关的编程一方面会给完成实验的人员制造不小的麻烦。另外更为重要的是这些容并不属于操作系统原理的畴。因此我们所设计的文件系统程序与真正的文件系统在某些方面有着本质的不同,下面的表是一个大致的比较。
实验设计的文件系统 自定义系统文件格式
二进制格式 自定义系统文件格式
依赖其他操作系统 不依赖其他操作系统
调用库函数访问外存 调用终端访问外存
四 几个重要算法
inti,flag=0,j,k=0,flag1=0,flag2
inti;
1
i=0
a=strlen(filename);
i<sys1.fatblocknum
IF
i++
1
fseek(fp,(sys1.fatblocknum+sys1.resblocknum)*BlockSize,0);
Multi
returnfp;
FOR
打开系统算法 建立文件算法 现实目录算法
见代码段2 见代码段5 见代码段4
读文件快算法
删除文件算法 见代码段6 见代码段10
获取文件指针算法 关闭文件算法 文件写算法
见代码段8 见代码段9 见代码段11
五 程序说明
1、源文件的简要说明
实验所提供的代码为C语言所编写,该程序模拟文件系统所提供的操作
2、程序操作界面
操作界面是用creat命令创建文件成功之后
再使用list命令现实文件,其他操作不再一一例举。
六 参考文献
计算机操作系统(第三版) 汤小丹等主编 电子科技大学
C程序设计(第三版) 谭浩强主编 清华大学
C/C++函数库查询辞典湘沪科技编著中国铁道
计算机科学与技术系课程设计评分表
课题名称: 高校科研管理系统
项 目
评 价
设计方案的合理性与创造性
设计与调试结果
设计说明书的质量
答辩述与回答问题情况
课程设计周表现情况
综合成绩
教师签名:
日 期:
(注:1.此页附在课程设计报告之后;2.综合成绩按优、良、中、与格和不与格五级评定。)
附件
//-------------------------代码1--------------------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BlockSize 512
#define DirSize 32
#define RootSize 2
struct ReserveBlock{
int sysblocknum;/*文件系统总扇区数*/
int resblocknum;/*保留扇区扇区数*/
int fatblocknum;/*FAT表扇区数*/
int rootblocknum;/*根目录区扇区数*/
char fillchar[BlockSize-4*sizeof(int)];/*填充字节*/
};
struct DirBlock{
char filename[11]; /*文件名限长11个字符*/
char fillchar[DirSize-4*sizeof(int)-sizeof(long int)-11];
/*填充字节*/
long filelen; /*文件长度*/
int year,month,day; /*日期*/
int firstblockaddr; /*文件首块扇区号*/
};
struct FCBBlock{
int fileid; /*文件标识*/
struct DirBlock fileinfo; /*目录信息*/
long filepos; /*文件读写指针*/
int fdtblockaddr; /*目录项所在块号*/
int fdtblockindex; /*目录项所在块序号*/
struct FCBBlock *next;/*指向下一个文件控制块的指针*/
};
struct ReserveBlock sys1;
struct FCBBlock *fcb;
struct DirBlock fil[32],*dir;/*目录项*/
int *fat1;
char *str,*ptr;
char fillchar[BlockSize];
FILE *fp;
//------------------------- 代码2--------------------------------
FILE *OPENSYS(char *filename)
{ int i;
fp=fopen(filename,"rb+");
fread(&sys1,1,BlockSize,fp);
fat1=(int *)malloc(sys1.sysblocknum);
for(i=0;i<sys1.fatblocknum;i++)
fread(fat1,sizeof(int)*sys1.sysblocknum,1,fp);/*把基本文件系统都读进来*/
fseek(fp,(sys1.fatblocknum+sys1.resblocknum)*BlockSize,0);/*改指针位置*/
dir=fil;/*目录指针*/
fread(dir,DirSize*32,1,fp);
return fp;
}
//-------------------------代码3--------------------------------
int CLOSESYS(FILE *stream)
{ int i;
fseek(stream,sys1.resblocknum*BlockSize,0);
fwrite(fat1,sizeof(int)*sys1.sysblocknum,1,stream);
fseek(fp,(sys1.fatblocknum+sys1.resblocknum)*BlockSize,0);
fwrite(dir,DirSize*32,1,fp);
fclose(fp);
return 1;
}
//-------------------------代码4--------------------------------
void LISTDIR(void)/*显示目录*/
{ int i,flag=0;
for(i=0;i<32;i++)
{ if(fil[i].firstblockaddr!=0)
{ if(flag==0)
printf("filename \n");
flag=1; /*标示*/
printf("%s\n",fil[i].filename);
}
}
}
//-------------------------代码5--------------------------------
int FCREATE(char *filename)/*建立文件*/
{ int i,flag=0,j,k=0,flag1=0,flag2=0,a;
int n,m;
while(1)
{a=strlen(filename);/*文件名长度*/
if(a>10)
{printf("zhe file length too long!\n");
printf("input file name again:");
scanf("%s",filename);
}else
break;
}
while(1)
{ for(i=0;i<32;i++)
if(strcmp(filename,fil[i].filename)==0)
{ printf("the name already exist \n");
printf("input name again:");
flag1=1;
break;
}
if(flag1==0)
break;
scanf("%s",filename);
flag1=0;
}
for(i=(sys1.fatblocknum+sys1.resblocknum+sys1.rootblocknum);i<sys1.sysblocknum;i++)
if(fat1[i]==0)
flag++;/*统计磁盘上为空数目*/
if(flag==0)
{ printf("ci pan yi man");/*统计结果为0,则磁盘已满*/
return 0;
}
printf("kong xian kuai shu:%d\n",flag);
printf("input file length:");
for(j=0;j<32;j++)
if(fil[j].firstblockaddr==0)
break;
while(1)
{scanf("%d",&dir[j].filelen);/*输入目录项中文件的长度*/
n=(dir[j].filelen/BlockSize)+(dir[j].filelen%BlockSize?1:0);
if(n<0||n>flag)/*文件长度小于0或大于空闲的空间 */
{printf("input length too long!\n");
printf("input again:");
} else
break;
}
for(i=(sys1.fatblocknum+sys1.resblocknum+sys1.rootblocknum);i<sys1.sysblocknum;i++)/*文件容区域*/
{ if(fat1[i]==0)
{ k++;
if(flag2==0)
{ dir[j].firstblockaddr=i+1;
flag2=1; }
else
{ if(k>=n)/*n 文件长度*/
{ fat1[m]=i+1;
fat1[i]=-1;
break;
}else
fat1[m]=i+1;
}
m=i;
}
}
strcpy(dir[j].filename,filename);
dir[j].filename[a]='\0';
printf("input year:");
scanf("%d",&dir[j].year);
printf("input month:");
scanf("%d",&dir[j].month);
printf("input day:");
scanf("%d",&dir[j].day);
return (1);
}
//-------------------------代码6--------------------------------
int FDELETE(char *filename)/*删除文件 */
{int i,j,k,n,flag=0;
struct FCBBlock *p;/*文件控制块指针*/
p=fcb;
while(p)
{if(strcmp(filename,fil[p->fdtblockindex].filename)==0)/*目录项所在序号 */
{printf("the file has open,please close it before delete !\n");
return 0;
} else
p=p->next;
}
for(i=0;i<32;i++)/*查找要关闭的文件 */
if(strcmp(filename,fil[i].filename)==0)
{ flag=1;
break;
}
if(flag==0)
{printf("file cannot find!\n");
return 0;
}
j=fil[i].firstblockaddr;
while(1)
{ k=fat1[j-1];
fseek(fp,(j-1)*BlockSize,0);/*将指针指向文件的第一个扇区的位置 */
fwrite(&fillchar,1,BlockSize,fp);
fat1[j-1]=0;
if(k==-1)
break;
else
j=k;
}
memset(&fil[i],0,DirSize);
return 1;
}
//-------------------------代码7--------------------------------
int FOPEN(char *filename)/*打开文件*/
{ int i,j=0,k,flag=0;
struct FCBBlock *p,*q,*r;
p=fcb;
for(i=0;i<32;i++)
if(strcmp(filename,fil[i].filename)==0)/*找到要打开的文件*/
{ flag=1;
break;
}
if(flag==0)
{printf("file cannot find!\n");
return 0;
}
while(p)
{j++;
if(strcmp(filename,fil[p->fdtblockindex].filename)==0)
{ printf("zhe file has open!\n");
return 0;
}
q=p;
p=p->next;
}
if(fcb==NULL)
{ fcb=(struct FCBBlock *)malloc(sizeof(struct FCBBlock));
fcb->fileid=j+1;/*文件标示*/
fcb->filepos=0;/*文件读写指针 */
fcb->next=NULL;/*指向下一个文件控制指针 */
fcb->fdtblockindex=i;
}
else
{ r=(struct FCBBlock *)malloc(sizeof(struct FCBBlock));
r->fileid=j+1;
r->filepos=0;
r->next=NULL;
r->fdtblockindex=i;
q->next=r;
} /*f->next=NULL; */
return 1;
}
//-------------------------代码8--------------------------------
long FGETLEN(int fileid)/*获取文件指针 */
{ struct FCBBlock *p;
p=fcb;
while(p)
{if(p->fileid==fileid)/*寻找要找的指针*/
return(p->filepos);
p=p->next;
}
printf("get faile!\n");
return(0);
}
//-------------------------代码9--------------------------------
int FCLOSE(char *filename)/*关闭文件 */
{ int flag=0;
struct FCBBlock *f,*p;
f=fcb;
if(strcmp(filename,fil[fcb->fdtblockindex].filename)==0)
{ flag=1;
fcb=fcb->next;
p=fcb;
while(p)
{p->fileid-=1;
p=p->next;
}
return flag;
}
p=f;
f=f->next;
while(f)
{
if(strcmp(filename,fil[f->fdtblockindex].filename)==0)
{ flag=1;
p=f->next;
/*p=p->next;*/
while(p)
{ p=p->next;
p->fileid-=1;
}
free(f);
return flag;
}
p=f;
f=
展开阅读全文