《2022年文件系统——Hash》由会员分享,可在线阅读,更多相关《2022年文件系统——Hash(11页珍藏版)》请在金锄头文库上搜索。
1、文件系统 Hash一、实验目的1、理解 linux 文件系统的内部技术2、掌握 linux 与文件有关的系统调用命令,并在此基础上建立面向随机检索的 hash结构文件。二、实验内容与设计思想实验内容:1、 参考教程中 Hash文件构造算法, 设计一组 Hash文件函数,包括 Hash文件创建、打开、关闭、读、写等。2、编写测试程序,通过记录保存、查找、删除等操作,检查上述Hash文件是否实现相关功能。三、实验使用环境Linux Redhat4 四、实验结果实验代码:HashFile.h #include #define COLLISIONFACTOR 0.5 /Hash函数冲突因子struct
2、 HashFileHeader int sig; /Hash文件印鉴int reclen; /记录长度int total_rec_num; /总记录数int current_rec_num; /当前记录数; struct CFTag char collision; /冲突计数char free; /空闲标志; /函数声明int hashfile_creat(const char *filename,mode_t mode,int reclen,int recnum); int hashfile_open(const char *filename,int flags, mode_t mode);
3、 int hashfile_close(int fd); int hashfile_read(int fd,int keyoffset,int keylen,void *buf); int hashfile_write(int fd,int keyoffset,int keylen,void *buf); int hashfile_delrec(int fd,int keyoffset,int keylen,void *buf); int hashfile_findrec(int fd,int keyoffset,int keylen,void *buf); int hashfile_save
4、rec(int fd,int keyoffset,int keylen,void *buf); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 11 页 - - - - - - - - - int hash(int keyoffset,int keylen,void *buf,int recnum); int checkHashFileFull(int fd); int readHashFileHeader(int fd,struct HashFileHeader *hf
5、h ) ; HashFile.c #include #include #include #include #include #include HashFile.h int hashfile_creat(const char *filename,mode_t mode,int reclen,int total_rec_num) struct HashFileHeader hfh; int fd; int rtn; char *buf; int i=0; hfh.sig=31415926; hfh.reclen=reclen; hfh.total_rec_num=total_rec_num; hf
6、h.current_rec_num=0; /fd=open(filename,mode); fd=creat(filename,mode); if(fd!=-1) rtn=write(fd,&hfh,sizeof(struct HashFileHeader); /lseek(fd,sizeof(struct HashFileHeader),SEEK_SET); if(rtn!=-1) buf=(char*)malloc(reclen+sizeof(struct CFTag)*total_rec_num); memset(buf,0,(reclen+sizeof(struct CFTag)*to
7、tal_rec_num); rtn=write(fd,buf,(reclen+sizeof(struct CFTag)*total_rec_num); free(buf); close(fd); return rtn; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 11 页 - - - - - - - - - else close(fd); return -1; int hashfile_open(const char *filename,int flags, mode
8、_t mode) int fd=open(filename,flags,mode); struct HashFileHeader hfh; if(read(fd,&hfh,sizeof(struct HashFileHeader)!=-1) lseek(fd,0,SEEK_SET); if(hfh.sig=31415926) return fd; else return -1; else return -1; int hashfile_close(int fd) return close(fd); int hashfile_read(int fd,int keyoffset,int keyle
9、n,void *buf) struct HashFileHeader hfh; readHashFileHeader(fd,&hfh); int offset=hashfile_findrec(fd,keyoffset,keylen,buf); if(offset!=-1) lseek(fd,offset+sizeof(struct CFTag),SEEK_SET); return read(fd,buf,hfh.reclen); else return -1; int hashfile_write(int fd,int keyoffset,int keylen,void *buf) 名师资料
10、总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 11 页 - - - - - - - - - return hashfile_saverec(fd,keyoffset,keylen,buf); /return -1; int hashfile_delrec(int fd,int keyoffset,int keylen,void *buf) int offset; offset=hashfile_findrec(fd,keyoffset,keylen,buf); if(offse
11、t!=-1) struct CFTag tag; read(fd,&tag,sizeof(struct CFTag); tag.free=0; /置空闲标志lseek(fd,offset,SEEK_SET); write(fd,&tag,sizeof(struct CFTag); struct HashFileHeader hfh; readHashFileHeader(fd,&hfh); int addr=hash(keyoffset,keylen,buf,hfh.total_rec_num); offset=sizeof(struct HashFileHeader)+addr*(hfh.r
12、eclen+sizeof(struct CFTag); if(lseek(fd,offset,SEEK_SET)=-1) return -1; read(fd,&tag,sizeof(struct CFTag); tag.collision-; /冲突记数减 1 lseek(fd,offset,SEEK_SET); / write(fd,&tag,sizeof(struct CFTag); hfh.current_rec_num-; /当前记录数减 1 lseek(fd,0,SEEK_SET); write(fd,&hfh,sizeof(struct HashFileHeader); else
13、 return -1; int hashfile_findrec(int fd,int keyoffset,int keylen,void *buf) struct HashFileHeader hfh; readHashFileHeader(fd,&hfh); int addr=hash(keyoffset,keylen,buf,hfh.total_rec_num); int offset=sizeof(struct HashFileHeader)+addr*(hfh.reclen+sizeof(struct CFTag); if(lseek(fd,offset,SEEK_SET)=-1)
14、return -1; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 11 页 - - - - - - - - - struct CFTag tag; read(fd,&tag,sizeof(struct CFTag); char count=tag.collision; if(count=0) return -1; /不存在recfree: if(tag.free=0) offset+=hfh.reclen+sizeof(struct CFTag); if(lseek(
15、fd,offset,SEEK_SET)=-1) return -1; read(fd,&tag,sizeof(struct CFTag); goto recfree; else char *p=(char*)malloc(hfh.reclen*sizeof(char); read(fd,p,hfh.reclen); /printf(Record is %d,%sn,(struct jtRecord*)p)-key,(struct jtRecord*)p)-other); char *p1,*p2; p1=(char*)buf+keyoffset; p2=p+keyoffset; int j=0
16、; while(*p1=*p2)&(j=lseek(fd,0,SEEK_END) offset=sizeof(struct HashFileHeader);/reach at end,then rewind if(lseek(fd,offset,SEEK_SET)=-1) return -1; read(fd,&tag,sizeof(struct CFTag); tag.free=1; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 11 页 - - - - - - -
17、- - lseek(fd,sizeof(struct CFTag)*(-1),SEEK_CUR); write(fd,&tag,sizeof(struct CFTag); write(fd,buf,hfh.reclen); hfh.current_rec_num+; /当前记录数加 1 lseek(fd,0,SEEK_SET); return write(fd,&hfh,sizeof(struct HashFileHeader); /存入记录 int hash(int keyoffset,int keylen,void *buf,int total_rec_num) int i=0; char
18、 *p=(char *)buf+keyoffset; int addr=0; for(i=0;ikeylen;i+) addr+=(int)(*p); p+; return addr%(int)(total_rec_num*COLLISIONFACTOR); int readHashFileHeader(int fd,struct HashFileHeader *hfh ) lseek(fd,0,SEEK_SET); return read(fd,hfh,sizeof(struct HashFileHeader); int checkHashFileFull(int fd) struct Ha
19、shFileHeader hfh; readHashFileHeader(fd,&hfh); if(hfh.current_rec_numhfh.total_rec_num) return 0; else return 1; jtRecord.h #define RECORDLEN 32 struct jtRecord int key; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 11 页 - - - - - - - - - char otherRECORDLEN-s
20、izeof(int); ; #ifdef HAVE_CONFIG_H #include #endif jtRecord.c #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include HashFile.h #include jtRecord.h #define KEYOFFSET 0 #define KEYLEN sizeof(int) #define FILENAME jing.hash void showHashFile(); int
21、 main(int argc, char *argv) struct jtRecord rec6= 1,jing,2,wang,3,li,4,zhang,5,qing,6,yuan ; int j=0; for(j=0;j6;j+) printf(t,recj.key,hash(KEYOFFSET,KEYLEN,&recj,6); int 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 11 页 - - - - - - - - - fd=hashfile_creat(FI
22、LENAME,O_RDWR|O_CREAT,RECORDLEN,6); int i=0; printf(nOpen ans Save Record.n); fd=hashfile_open(FILENAME,O_RDWR,0); for(i=0;i6;i+) hashfile_saverec(fd,KEYOFFSET,KEYLEN,&reci); hashfile_close(fd); showHashFile(); /Demo find Rec printf(nFind Record.); fd=hashfile_open(FILENAME,O_RDWR,0); int offset=has
23、hfile_findrec(fd,KEYOFFSET,KEYLEN,&rec4); printf(noffset is %dn,offset); hashfile_close(fd); struct jtRecord jt; struct CFTag tag; fd=open(FILENAME,O_RDWR); lseek(fd,offset,SEEK_SET); read(fd,&tag,sizeof(struct CFTag); printf(Tag is t,tag.collision,tag.free); read(fd,&jt,sizeof(struct jtRecord); pri
24、ntf(Record is %d,%sn,jt.key,jt.other); /Demo Delete Rec printf(nDelete Record.); fd=hashfile_open(FILENAME,O_RDWR,0); hashfile_delrec(fd,KEYOFFSET,KEYLEN,&rec2); hashfile_close(fd); showHashFile(); /Demo Read fd=hashfile_open(FILENAME,O_RDWR,0); char buf32; memcpy(buf,&rec1,KEYLEN); hashfile_read(fd
25、,KEYOFFSET,KEYLEN,buf); printf(nRead Record is %d,%sn,(struct jtRecord*)buf)-key,(struct jtRecord*)buf)-other); hashfile_close(fd); /Demo Write 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 9 页,共 11 页 - - - - - - - - - printf(nWrite Record.); fd=hashfile_open(FILENA
26、ME,O_RDWR,0); hashfile_write(fd,KEYOFFSET,KEYLEN,&rec3); hashfile_close(fd); showHashFile(); return 0; void showHashFile() int fd; printf(n); fd=open(FILENAME,O_RDWR); lseek(fd,sizeof(struct HashFileHeader),SEEK_SET); struct jtRecord jt; struct CFTag tag; while(1) if (read(fd,&tag,sizeof(struct CFTa
27、g)=0) break; printf(Tag is t,tag.collision,tag.free); if(read(fd,&jt,sizeof(struct jtRecord)=0) break; printf(Record is %d,%sn,jt.key,jt.other); close(fd); 运行结果:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 10 页,共 11 页 - - - - - - - - - 五、实验小结通过这次实验, 在同学的帮助下学会了如何同时编译多个文件,即在-gcc o后面同时添加 2 个文件名便可同时编译成功2 个文件了。六、附录网络编程技术与应用名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 11 页,共 11 页 - - - - - - - - -