模拟单级目录单级索引(索引文件系统)_第1页
模拟单级目录单级索引(索引文件系统)_第2页
模拟单级目录单级索引(索引文件系统)_第3页
模拟单级目录单级索引(索引文件系统)_第4页
模拟单级目录单级索引(索引文件系统)_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 目录1. 需求分析12. 程序的功能23. 程序的基本设计思路34. 主要的数据结构45. 数据流程图56. 调试运行87. 心得体会108. 附录11一 需求分析:使用链接域将同一文件的各索引块按顺序连接起来。基本设计要求:1、实现如下文件系统功能(过程或函数):打开文件系统 FILE *OPENSYS(char *filename);关闭文件系统 int CLOSESYS(FILE *stream);显示目录 void LISTDIR(void);建立文件 int FCREATE(char *filename);删除文件 int FDELETE(char *filename);打开文件

2、int FOPEN(char *filename);关闭文件 int FCLOSE(int fileid);文件块读 int FREAD(void *ptr, int n, int fileid);文件块写 int FWRITE(void *ptr, int n, int fileid);判断文件结束 int FEOF(int fileid);获取文件指针 long FGETPOS(int fileid);设置文件指针 int FSETPOS(int fileid, long offset);取得文件长度 long FGETLEN(char *filename);2、提供文件系统创建程序3、有

3、功能检测模块4、为简化程序设计,假定目录区域大小固定。可以使用的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, si

4、ze_t n, FILE *stream);二 程序的功能:模拟实现单级目录、单级索引的索引文件系统,包含的功能有:文件的创建,文件删除,读,写,打开,关闭以及能显示目录。在创建文件时,系统首先为新文件分配所需的外存空间,并且在文件系统的相应目录中,建立一个目录项,该目录项纪录了新文件的文件名以及在外存中的地址等属性。它是目录文件中的一个记录,它与文件时一一对应。当不需要某个文件时,便可以把它从文件系统中删除。这时执行的是与创建文件相反的操作。系统先从目录中找到要删除的文件项,使之成为空项,紧接着回收该文件的存储空间,用于下次分配。通过读指针,将位于外部存储介质上的数据读入到内存缓冲区这样就实

5、现了文件的读取,通过写指针,将内存缓冲区中的数据写入到位于外部存储介质上的文件中。在开始使用文件时,首先必须打开文件。这可以将文件属性信息装入内存,以便以后快速查用。在完成文件使用后,应该关闭文件。这不但是为了释放内存空间,而且也因为许多系统常常限制可以同时打开的文件数。当创建文件时,先在目录表中查找是否存在此文件表,若存在则表示文件同名不能创建,否则在目录表中为此文件先建立一个目录项,保存文件的一些基本属性,如创建日期、大小、文件名等,并保存文件的首索引块扇区号,对文件读写也是先在目录项里查找文件是否存在,再根据文件的首索引块扇区号,查找对应块号中的内容对其进行读写操作,删除一个文件后回收为

6、其分配的空间,并更新目录表、修改文件控制块。显示目录项可以显示文件名、长度以及创建日期。三 程序的基本设计思路:单机目录,单级索引的索引文件系统:单级目录,它是整个目录组织是一个线性结构,系统中的所有文件都建立在一张目录表中。它主要用于单用户操作系统,具有结构简单、文件多时目录检索时间长和有命名冲突等特点;文件的索引结构实际上就是把链接结构中的指针取出来集中存放在一起,这样它既能够完全利用每一个存储块的最大存储量,又保持物理块为2的幂。索引文件系统它是指为每一文件建立一张索引表,将文件中每个记录的记录号、长度和指向该记录的指针记入索引表中的一种文件组织形式。由于索引表本身是一个定长记录文件,因

7、此可以十分方便地检索到相应记录的索引表项,从而可方便地对主文件中的记录实现直接存取。模拟实现单机目录,单级索引的索引文件系统基本思路:用使用链接域将同一文件的各索引块按顺序连接起来。在一个文件系统中对文件进行操作,实现文件的创建、读写等等操作。在创建文件时先在目录项中进行查找,若创建的文件已存在,文件的创建首先检验目录是否为空,为空则把文件夹或文件连接到该目录下,不为空则把检查目录下是否有同名文件夹或文件,有则提示创建不成功,而文件夹打开是则把文件夹名称及其地址压入打开文件夹栈,文件关闭则把文件夹名称及其地址从打开文件夹中抛出。文件夹和文件的删除,文件夹下没有打开的文件或文件没有打开才能删除,

8、否则删除失败,每次操作成功都要更改目录和索引信息。该过程都保存在文件中,是对文件的操作。本系统建于Windows平台,开发环境为microsoft visual C+。四 主要数据结构:单级目录单级索引文件系统:常量#define BlockSize 512#define DirSize 32保留扇区结构struct ReserveBlockint sysblocknum; /*文件系统总扇区数*/int resblocknum; /*保留扇区扇区数*/int mapblocknum; /*字节映像图扇区数*/int rootblocknum; /*根目录区扇区数*/char fillchar

9、BlockSize-4*sizeof(int); /*填充字节*/;目录结构struct DirBlockchar filename11; /*文件名限长11个字符*/char fillcharDirSize-4*sizeof(int)-sizeof(long int)-11; /*填充字节*/long filelen; /*文件长度*/int year,month,day; /*定义年月日*/int firstindexaddr; /*文件首索引块扇区号*/; 索引块结构struct IndexBlockint dataaddrBlockSize/sizeof(int)-1; /*数据块块号

10、数组*/int nextindexaddr; /*本文件下一索引块块号*/; 索引节点结构 struct IndexNodestruct IndexBlock block; /*索引块数据*/int blockaddr; /*本节点索引块块号*/struct IndexNode *nextnode; /*指向下一索引节点的指针*/;FCB(文件控制块)结构struct FCBBlockint fileid; /*文件标识*/struct DirBlock fileinfo; /*目录信息*/long filepos; /*文件读写指针*/int fdtblockaddr; /*目录项所在块号*

11、/int fdtblockindex; /*目录项所在块内序号*/struct FCBBlock *next; /*指向下一个文件控制块的指针*/ struct IndexNode *firstindexnode; /*指向第一个索引节点的指针*/五 数据流程图:六 调试运行:进入功能菜单,选择要执行的功能,如下图一所示:创建文件,如下图二所示:写文件,如下图三所示:显示文件目录,如下图四所示:删除文件。如下图五所示:退出文件系统,如图六所示:七 心得体会:为期两周的操作系统课设结束了,这次的课设给了我很大的收获,不仅仅对计算机的知识有了进一步的了解,并且对我的实践能力提高的帮助也是相当大。刚

12、看到课程任务书时觉得这是很简单的课程设计,因为它与以往的不同的是,功能的编码实现部分是已经提供的了,我们需要做的只是将它连接起来,所以一开始还是有些漫不经心,当课设的截止时间慢慢迫近,就开始用心做时,才发现远远没有自己想象中简单。首先要弄明白的是功能模块的作用,之间改怎样联系。其次还要了解变量之间的联系。总的来说就是要弄懂总个程序。但脑袋里面没有一个总体的概念是很难完成的。阅览代码就要充分了解设计者的思想。一直不停的阅览分析,调试,修修改改才完成了这次课设的代码部分。这也让我明白了一个道理,读懂他人的思想并不比自己编程来的简单。 在完成代码的过程中,出现了很多错误,一个一个慢慢修改。这让我体会

13、到养成一种良好的编程习惯是非常重要的,不仅仅是变量的编写错误这些小毛病。还有不能一条一条语句编写,首先就是要够好思路才能达到事半功倍的效果。而且代码的编写格式也非常重要,这不仅仅是美观的问题而且便于对代码理解。编程也是交流精神也是非常重要的,由于自己的惯性思维对自己的错误很难发现,所以需要别人的帮助更快更容易发现错误。代码编写过程中,同学的热心帮助,老师的细心指导是很重要的。其次,代码编写能力也是很重要的,一个文件的创建更或是输入输出都有问题的话,需要借助资料,这是很麻烦的,最基本的功夫不到家有想法也是很难实现的。在这次课设中我学到了设计简单磁盘管理的思想,单级目录,单级索引的文件索引系统。重

14、要的是培养了多多交流的精神,这简直太重要了。在课设过程中,在遇到问题的时候,同学们愿意放下自己手中的是来帮我解决,让我感到很温暖,从同学那里也学到了不少知识。总之,很感谢老师和同学的帮助。这次的课程设计已经结束了,但学习还没有结束,这次的领悟就是丰富的知识,和动手能力的培养是多么的重要。我将不断丰富自己的知识,在动手中培养自己的实际操作能力。八 附录:头文件:#define BlockSize 512#define DirSize 32#define RootSize 2struct ReserveBlock int sysblocknum;/*文件系统总扇区数*/ int resblockn

15、um;/*保留扇区扇区数*/ int mapblocknum;/*字节映像图扇区数*/ int rootblocknum;/*根目录区扇区数*/ char fillcharBlockSize-4*sizeof(int);/*填充字节*/;struct DirBlock char filename11; /*文件名限长11个字符*/ char fillcharDirSize-4*sizeof(int)-sizeof(long int)-11; /*填充字节*/ long filelen; /*文件长度*/ int year,month,day; /*日期*/ int firstindexaddr

16、; /*文件首索引块扇区号*/;struct IndexBlock int dataaddrBlockSize/sizeof(int)-1; /*数据块块号数组*/ int nextindexaddr; /*本文件下一索引块块号*/;struct IndexNode struct IndexBlock block; /*索引块数据*/ int blockaddr; /*本节点索引块块号*/ struct IndexNode *nextnode;/*指向下一索引节点的指针*/;struct FCBBlock int fileid; /*文件标识*/ struct DirBlock fileinf

17、o; /*目录信息*/ long filepos; /*文件读写指针*/ int fdtblockaddr; /*目录项所在块号*/ int fdtblockindex; /*目录项所在块内序号*/ struct FCBBlock *next;/*指向下一个文件控制块的指针*/ struct IndexNode *firstindexnode;/*指向第一个索引节点的指针*/;#include index.h#include #include #include int main() struct ReserveBlock sys; char filename=indexsys.dat; cha

18、r fillcharBlockSize; char *map; int i,j; FILE *fp; memset(&sys,255,BlockSize); printf(Please Input FileSystems Block Num(532767):); scanf(%d,&(sys.sysblocknum); sys.resblocknum=1; sys.mapblocknum=sys.sysblocknum/(BlockSize/sizeof(char)+/求出FAT表区所需的磁盘块数,即存储磁盘块的使用情况所需的磁盘块数 (sys.sysblocknum%(BlockSize/s

19、izeof(char)?1:0); map=(char*)malloc(BlockSize*sys.mapblocknum);/在内存中分配FAT表区同样大小的空间,以便以后存入磁盘 memset(map,255,BlockSize*sys.mapblocknum);/填充为FAT表区分配的内存空间(全部填充) memset(map,0,sizeof(char)*sys.sysblocknum);/填充实际使用部分的FAT分区表部分 sys.rootblocknum=RootSize;/根目录区分配的块数,这里固定为2块 j=sys.resblocknum+sys.mapblocknum+sy

20、s.rootblocknum;/保留块数+FAT表区块数+根目录块数 for (i=0;ij;i+) mapi=1; /标注这些非文件存储使用区的块部分已经使用 memset(&fillchar,0,BlockSize);/用0填充一块,512字节 fp=fopen(filename,w+b); fwrite(&sys,1,BlockSize,fp);/文件中写入第一块进去,即为保留扇区块,其中存储磁盘的块数分配信息,即ReserveBlock块的信息 for (i=0;isys.mapblocknum;i+) fwrite(map+i*BlockSize/sizeof(char),1,Blo

21、ckSize,fp);/map可能有多块,每次只将一块(512B)写入文件中去;这是第二次写入,可能写入多块 j=sys.resblocknum+sys.mapblocknum;/保留块数+FAT表区所用块数,用于求出用于存文件的剩余块数 for(i=0;i(sys.sysblocknum-j);i+) fwrite(&fillchar,1,BlockSize,fp);/在文件中存入用于存放文件的块数,每次存一块,这些存入的块都将用来存放文件 fclose(fp);/关闭打开的文件 free(map);/释放为map分配的内存空间 return 0;#include index.h#inclu

22、de #include #include FILE *filesystem;struct ReserveBlock sys;char *map;struct FCBBlock *fcblist;/*a、打开文件系统 */FILE *OPENSYS(char *filename) int i; FILE *fp; fp=fopen(filename,r+b); fread(&sys,1,BlockSize,fp);/将第一块保留扇区的内容读入内存,其中存放模拟文件系统的扇区分配信息 map=(char *)malloc(BlockSize*sys.mapblocknum); for(i=0;is

23、ys.mapblocknum;i+) fread(map+i*BlockSize/sizeof(char),1,BlockSize,fp);/读取扇区块使用情况的扇区块的信息,这里面标记了模拟文件系统磁盘块的每块的使用状态 fcblist=NULL;/置已打开文件的列表为空 return fp;/*b、关闭文件系统 */int CLOSESYS(FILE *stream) int i; fseek(stream,sys.resblocknum*BlockSize,SEEK_SET); for(i=0;isys.mapblocknum;i+) fwrite(map+i*BlockSize/siz

24、eof(char),1,BlockSize,stream);/将模拟文件系统的文件块使用信息重新写入磁盘 fclose(stream); free(map); return 1;/*c、显示目录 */void LISTDIR(void) int i,j; struct DirBlock *fdt,*fdt1; fdt1=(struct DirBlock *)malloc(BlockSize);/一个目录块占32B,这里分配512B,即16个目录的存放空间 fseek(filesystem,(sys.resblocknum+sys.mapblocknum)*BlockSize,SEEK_SET)

25、;/将文件指针置于目录块的块首 printf(-filename-filelength-date-n); for(i=0;isys.rootblocknum;i+) fread(fdt1,1,BlockSize,filesystem);/每次读取一块 fdt=fdt1; for(j=0;jfilename0!=0) printf(%12s%12ld%5d-%2d-%2dn,fdt-filename,fdt-filelen, fdt-year,fdt-month,fdt-day); fdt+; free(fdt1);/*d、建立文件 */int FCREATE(char *filename)/

26、int i,j; struct DirBlock *fdt,*fdt1; long addr; fdt1=(struct DirBlock *)malloc(BlockSize); addr=(sys.resblocknum+sys.mapblocknum)*BlockSize; fseek(filesystem,addr,SEEK_SET); for(i=0;isys.rootblocknum;i+) fread(fdt1,1,BlockSize,filesystem); fdt=fdt1; for(j=0;jfilename,filename)/判断要建立的文件的文件名是否已经存在 pri

27、ntf(Duplicate filename !n); free(fdt1); return 0; else fdt+; fseek(filesystem,addr,SEEK_SET); for(i=0;isys.rootblocknum;i+)/读取根目录块数,一次读取一块 fread(fdt1,1,BlockSize,filesystem); fdt=fdt1; for(j=0;jfilename0=0)/如果读取到空闲空间就执行加入一条文件目录操作 strcpy(fdt-filename,filename);/写入文件名 fdt-filelen=0; fdt-year=2003; fdt

28、-month=3; fdt-day=12; fdt-firstindexaddr=0;/设置该文件存入数据时所用到的第一个盘块号为0 fseek(filesystem,addr,SEEK_SET);/若是第一块则置文件指针到目录块首,否则置文件指针到相应的末尾处 fwrite(fdt1,1,BlockSize,filesystem);/重新写入这一块的数据 free(fdt1); return 1; else fdt+; addr=ftell(filesystem);/非第一块时设置文件指针的位置 free(fdt1); return 0;/*e、删除文件 */int FDELETE(char

29、 *filename)/ int i,j,k,m; struct DirBlock *fdt; int blocknum; struct FCBBlock *p; struct IndexBlock ib; p=fcblist; while(p) /若已经打开要删除的文件,则拒绝删除 if (!strcmp(p-fileinfo.filename,filename) return 0; else p=p-next; fdt=(struct DirBlock *)malloc(BlockSize); blocknum=sys.resblocknum+sys.mapblocknum; for(i=

30、0;isys.rootblocknum;i+) fseek(filesystem,blocknum*BlockSize,SEEK_SET); fread(fdt,1,BlockSize,filesystem); /从目录块中获取该文件的信息 for(j=0;jfilename,filename) strcpy(fdt+j)-filename,);/在回收区内可以直接置0 k=(fdt+j)-firstindexaddr;/获取该文件内容所用的第一块的块号 while (k) fseek(filesystem,k*BlockSize,SEEK_SET); fread(&ib,1,BlockSiz

31、e,filesystem);/读取文件内容块的信息 mapk=0;/修改FAT表区中该块为未用状态 k=ib.nextindexaddr; for(m=0;m(BlockSize/sizeof(int)-1);m+) mapib.dataaddrm=0; fseek(filesystem,blocknum*BlockSize,SEEK_SET); fwrite(fdt,1,BlockSize,filesystem); free(fdt); return 1; blocknum+; free(fdt); return 0;/*f、打开文件 */int FOPEN(char *filename)

32、int i,j; struct DirBlock *fdt; int blocknum; struct FCBBlock *p; struct IndexNode *q,*r; fdt=(struct DirBlock *)malloc(BlockSize); blocknum=sys.resblocknum+sys.mapblocknum; for(i=0;isys.rootblocknum;i+) fseek(filesystem,blocknum*BlockSize,SEEK_SET); fread(fdt,1,BlockSize,filesystem);/将目录块中的内容逐块读出来 f

33、or(j=0;jfilename,filename) p=(struct FCBBlock *)malloc(sizeof(struct FCBBlock); p-next=fcblist;/找到该文件,就创建一个节点,插入到FCB链表中,采用头结点插入法 fcblist=p; if (p-next) /这里逻辑上反了,应该是如果是第一个打开的文件就置文件标识号为0,否则 p-fileid=p-next-fileid+1; /才是该索引节点的下一个节点的标识号加1即为这次打开文件的标识号 else p-fileid=1;/若是第一个打开的文件则置文件ID为1 p-fileinfo=*(fdt+

34、j); /*maybe need modify*/ / p-fdtblockaddr=blocknum; p-fdtblockindex=j; p-filepos=0;/打开一个文件,就将文件指针指向文件的开头处,逻辑上为0 if (p-fileinfo.firstindexaddr=0)/此处判断要打开的文件是否为空 p-firstindexnode=NULL; else q=(struct IndexNode *)malloc(sizeof(struct IndexNode); p-firstindexnode=q; q-blockaddr=p-fileinfo.firstindexadd

35、r; fseek(filesystem,q-blockaddr*BlockSize,SEEK_SET); fread(&q-block,1,BlockSize,filesystem); while (q-block.nextindexaddr!=0) r=q; q=(struct IndexNode *)malloc(sizeof(struct IndexNode); r-nextnode=q; q-blockaddr=r-block.nextindexaddr; fseek(filesystem,q-blockaddr*BlockSize,SEEK_SET); fread(&q-block,

36、1,BlockSize,filesystem); q-nextnode=NULL; free(fdt); return p-fileid; blocknum+; free(fdt); return 0;/*g、关闭文件 */int FCLOSE(int fileid)/ int i,j; struct FCBBlock *p,*q; struct DirBlock *fdt; struct IndexNode *r; q=fcblist; if (!q) return 0; if (q-fileid=fileid)/找到该文件并且其为FCB链表的头节点,就将其从FCB链表的表头中删掉 p=q;

37、 fcblist=q-next; else while (q-next&q-next-fileid!=fileid) q=q-next; if (!q-next)return 0;/如果没找到该文件就返回 p=q-next;/这里P即为要删除的节点 q-next=p-next;/删除节点p fseek(filesystem,p-fdtblockaddr*BlockSize,SEEK_SET);/将文件指针移动到所要关闭的文件所在的目录块的块首位置 fdt=(struct DirBlock*)malloc(BlockSize); fread(fdt,1,BlockSize,filesystem)

38、;/读取这整个目录块的内容 *(fdt+p-fdtblockindex)=p-fileinfo;/将读入的目录中的数据进行更新 fseek(filesystem,p-fdtblockaddr*BlockSize,SEEK_SET); fwrite(fdt,1,BlockSize,filesystem); /将更新后的数据写入文件中的原目录块中去 while (p-firstindexnode) /再逐块的将文件内容数据写入文件中去 r=p-firstindexnode; p-firstindexnode=r-nextnode; fseek(filesystem,r-blockaddr*Bloc

39、kSize,SEEK_SET); fwrite(&r-block,1,BlockSize,filesystem);/这里应该用FWRITE吧,因为如果打开文件后数据更新了,则所占用的块数也变了,所以。? free(p); free(fdt); return 1;/*h、文件块读 */int FREAD(void *ptr, int n, int fileid) struct FCBBlock *p; int indexorder,blocknum,i,j,k; long pos; char bufBlockSize; struct IndexNode *q; if (nfileid!=file

40、id) p=p-next; if (!p) return 0; if (p-filepos+n) p-fileinfo.filelen)/如果读取的字节数超过文件的长度,则只读取文件剩余的部分 n=p-fileinfo.filelen-p-filepos; / /* other*/ / pos=p-filepos;/取得文件的当前指针 q=p-firstindexnode;/取得文件所占块逻辑上的第一块的块号 indexorder=0; while (pos=BlockSize) indexorder+; if (indexorder=BlockSize/sizeof(int)-1) q=q-

41、nextnode; indexorder=0; pos-=BlockSize; blocknum=q-block.dataaddrindexorder; i=0;j=n; while (j) if (j=BlockSize-pos) k=BlockSize-pos; else k=j; fseek(filesystem,blocknum*BlockSize,SEEK_SET); fread(buf,1,BlockSize,filesystem); memcpy(char *)ptr+i,buf+pos,k); pos=0; i+=k; j-=k; p-filepos+=k; indexorde

42、r+; if (indexorder=BlockSize/sizeof(int)-1) q=q-nextnode; indexorder=0; blocknum=q-block.dataaddrindexorder; return n;/*need for FWRITE,append n block for file with this fileid*/int appendblock(int fileid,int n) struct FCBBlock *p; int i,j; struct IndexNode *q; if (nfileid!=fileid) p=p-next; if (!p)

43、 return 0;/如果在FCB索引中没有找到该应该打开的文件就返回 for(i=0;mapi!=0;i+);/查找空闲块,若找到即为第i块 if (i=sys.sysblocknum) return 0; /如果没有空闲块的话就返回 if (p-fileinfo.firstindexaddr=0)/如果该文件为空文件 p-fileinfo.firstindexaddr=i;/将找到的第一个空闲分区块分配给该文件,作为该文件的第一个分区块 mapi=1;/标记第i块被使用 p-firstindexnode=(struct IndexNode*)malloc(sizeof(struct Ind

44、exNode); memset(&p-firstindexnode-block,0,BlockSize); p-firstindexnode-blockaddr=i;/记录第一块所在的块号 p-firstindexnode-nextnode=NULL; for(;mapi!=0;i+);/再次判断,如果已经没有可以分配的文件块了就终止执行后面的代码,返回 if (i=sys.sysblocknum) return 0; q=p-firstindexnode;/以下三行定位到文件的最后一块处,即q指向文件块得最后一块 while (q-nextnode) q=q-nextnode; /*need modify*/ j=0; while (q-block.dataaddrj!=0)&(jnextnode=(struct IndexNode*)malloc(sizeof(struct IndexNode); q-block.nextindexaddr=i; mapi=1; q=q-nextnode; memset(&q-block,0,BlockSize);/填充最后的一块空间 q-blockaddr=i; q-nextnode=NULL; j=0; for(;mapi!=0;i+

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论