实验四文件系统
实验四文件系统
•
参考代码
• • • • HashFile.h HashFile.c 测试程序jtRecord.h 测试程序jtRecord.c
HashFile.h
#include <unistd.h> #define COLLISIONFACTOR 0.5 //Hash函数冲突 因子 struct HashFileHeader { int sig; //Hash文件印鉴 int reclen; //记录长度 int total_rec_num; //总记录数 int current_rec_num; //当前记录数 };
int hashfile_write(int fd,int keyoffset,int keylen,void *buf) { 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(offset!=-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.reclen+sizeof(struct CFTag)); if(lseek(fd,offset,SEEK_SET)==-1) return -1;
操作系统实验_文件系统
广州大学学生实验报告开课学院及实验室:计算机科学与工程实验室 2015 年12 月8日实验课操作系统实验成绩程名称实验项实验4 文件系统指导老师陈康民目名称一、实验目的1. 对文件管理有进一步了解2. 利用文件备份实验加深对文件管理的了解3. 熟悉fopen()、fread()、 fwrite()、fclose() 的使用二、实验内容利用函数fopen(), fread(), fwrite(), fclose() 来实现简单的文件备份,即将一个文件的内容拷贝到另一个文件中去。
三、实验原理利用函数fopen(), fread(), fwrite(), fclose() 来实现简单的文件备份四、实验设备PC(操作系统:Fedora,含GCC)五、实验要求完成利用函数fopen(), fread(), fwrite(), fclose() 来实现简单的文件备份,即将一个文件的内容拷贝到另一个文件中去。
并进行分析参考程序提供错误解决方案。
六、实验程序9.c:#include <sys/types.h>#include <stdio.h>#include <stdlib.h>int main(void){char buf; //建立缓冲区FILE *source, *backup; //设立FILE结构指针if ((source = fopen("source.dat", "r")) == NULL) //若以只读形式source.dat成功打开,则fopen()返回FILE指针source{printf("Error in opening file.\n");exit(1);}if ((backup = fopen("backup.dat", "w")) == NULL) //若以只写形式backup.dat无法打开,则创建文件不成功{printf("Error in creating file.\n");exit(1);}while (fread(&buf, sizeof(buf), 1, source) == 1) //用fread函数读取source的一个buf大小的数据到缓冲区{if (fwrite(&buf, sizeof(buf), 1, backup) == 0) //用fwrite函数把一个buf大小的缓冲区数据写入backup{//若写入错误,则打印“写入文件错误”printf("Error in wrinting file.\n");exit(1);}}if (ferror(source)) //读取文件source出现错误{printf("Error in reading file.\n");exit(1);}if (fclose(source)) //source流的关闭出现错误{printf("Error in close file.\n");exit(1);}if (fclose(backup)) //backup流的关闭出现错误{printf("Error in close file.\n");exit(1);}return 0;}9.c结果截图实验结果1:源文件source.dat内容如下:编译运行后多了个Backup.dat文件实验分析1:此方案1,用char buf;重新定义缓冲区,程序中if (!(source = fopen("source.dat", "r")))和if (!(backup = fopen("backup.dat", "w")))中的表达式虽然没有错误,但这种写法不太好,因fopen()返回的是一个地址或者空值,这样写会影响程序的可读性,同时在某些机器上可能引发错误,所以改为if ((source = fopen("source.dat", "r")) == NULL)和if ((backup = fopen("backup.dat", "w")) == NULL)。
实验四文件操作
实验四文件操作一、实验目的1.熟悉和理解文件系统的概念和文件系统的类型。
2.掌握文件系统的挂载方法。
3.学会Linux中数据备份的方法。
4.了解Linux系统中文件系统的管理机制。
二、实验内容1.挂载文件系统。
2.监视文件系统状态。
3.维护文件系统。
4.软盘的使用。
5.硬盘的使用。
6.数据备份和压缩。
7.在GNOME下管理磁盘三、实验环境1.装有Linux系统的计算机。
2.软磁盘和光盘各一张。
四、实验步骤(一)挂载文件系统1.手工挂载文件系统①用mount命令挂载文件系统。
命令格式:mount [-fnrvw] [-t type] device dir其中:-t type:指定文件系统类型;device:待安装文件系统的块设备名;dir:安装点(目录);-f: 模拟一个文件系统的挂装过程,用它可以检查一个文件系统是否可以正确挂装。
-n:挂装一个文件系统,但不在fstab文件中生成与之对应的设置项。
-v:命令进展注释,给出mount命令每个操作步骤的注释。
-r:将文件系统挂载为只读模式;-w:将文件系统挂载为读写模式。
操作:在软驱中插入一张磁盘,然后将软驱挂载为msdos文件类型。
②挂载软磁盘的命令:mount -t msdos /dev/fd0 /mnt/floppy挂载完成后,用ls命令查看软磁盘中包括的文件。
③用mount命令还可以显示所有已安装的文件系统。
命令格式:mount [-hV]2.手工卸载文件系统用umount命令卸载文件系统。
命令格式:umount [-hV]umount [-a] [-n] [-v] [-t types]其中:-h:显示帮助信息。
-V:显示版本信息。
-a:表示要卸载/etc/fstab中的所有文件系统;-n:卸除时不要将信息存入/etc/mtab文件中。
-v:执行时显示详细的信息。
-t types:指定文件系统的类型。
操作:卸载软盘的msdos文件系统。
①命令:umount -t msdos /dev/fd0卸载完成后,从软盘驱动器中取出软盘。
实验四 磁盘和文件系统管理心得
实验四磁盘和文件系统管理心得前言实验四主要涉及磁盘和文件系统的管理,通过对磁盘分区、文件系统格式化、文件的创建、删除和修改等操作,我们能够更好地理解和掌握磁盘和文件系统的相关概念和原理。
本文将从以下几个方面对实验四的心得进行全面、详细、完整且深入地探讨。
磁盘分区的原理与方法磁盘分区是指将一个物理硬盘分成多个逻辑区域的操作。
通过对磁盘进行合理分区,可以充分利用磁盘空间,并为不同用途的数据提供不同的存储空间。
磁盘分区有两种常见的方法:主引导记录(Master Boot Record,MBR)分区和GUID分区表(GUID Partition Table,GPT)。
MBR分区MBR分区是一种传统的分区方式,适用于BIOS引导的系统。
MBR分区表将硬盘的第一个扇区(512字节)用于存储分区表的信息,包括主引导记录、分区表项等。
MBR分区最多支持4个主分区或3个主分区加一个扩展分区。
其中,扩展分区可以进一步划分逻辑分区。
GPT分区GPT分区是一种新的分区方式,适用于UEFI引导的系统。
GPT分区通过GUID(全局唯一标识符)来标识分区,解决了MBR分区的一些限制,如只能支持最多4个主分区等。
GPT分区表存储在硬盘末尾的一个独立区域,可以容纳更多的分区信息。
文件系统的选择与格式化文件系统是操作系统用来管理和组织文件的一种方式。
常见的文件系统有FAT32、NTFS、ext4等。
在进行文件系统格式化之前,我们需要选择适合自己需求的文件系统。
FAT32文件系统FAT32是一种通用的文件系统,在各个操作系统中都能够良好地兼容。
它支持的单个文件最大为4GB,簇大小可以灵活配置。
然而,FAT32文件系统对于大容量硬盘的利用率较低,而且不支持文件权限和加密等高级功能。
NTFS文件系统NTFS是Windows操作系统中常用的文件系统,它支持大容量硬盘,单个文件最大支持16TB。
NTFS文件系统具有更高的稳定性和安全性,支持文件权限、加密和压缩等功能。
实验四 磁盘和文件系统管理心得
实验四磁盘和文件系统管理心得实验四磁盘和文件系统管理心得一、实验背景磁盘和文件系统管理是计算机操作系统中非常重要的一部分,它涉及到了计算机存储和数据管理的方方面面。
在本次实验中,我们主要学习了磁盘的分区、格式化以及文件系统的创建与管理等内容。
二、实验过程1. 磁盘分区在Windows操作系统中,我们可以通过“磁盘管理”来对硬盘进行分区。
首先需要在“我的电脑”中找到硬盘驱动器,右键点击选择“管理”,进入“计算机管理”界面后,在左侧的菜单栏中选择“磁盘管理”,然后就可以对硬盘进行分区操作了。
2. 磁盘格式化在将硬盘进行分区之后,我们还需要对每个分区进行格式化。
格式化可以将硬盘上的数据清空,并为其创建一个新的文件系统。
在Windows操作系统中,我们同样可以通过“磁盘管理”来进行格式化操作。
3. 文件系统创建与管理在Linux操作系统中,我们可以使用mkfs命令来创建文件系统。
例如,在Ubuntu下创建ext4文件系统时,可以使用以下命令:sudo mkfs.ext4 /dev/sdb1其中,“/dev/sdb1”表示要创建文件系统的设备名称。
除了创建文件系统之外,我们还可以使用一些命令来管理文件系统。
例如,使用mount命令可以将文件系统挂载到指定的目录下:sudo mount /dev/sdb1 /mnt此时,/dev/sdb1设备上的文件系统就会被挂载到/mnt目录下。
另外,我们还可以使用umount命令来卸载已经挂载的文件系统:sudo umount /mnt三、实验心得通过本次实验,我对磁盘和文件系统管理有了更深入的了解。
在实际应用中,我们需要根据具体情况来对磁盘进行分区和格式化,并创建适合自己的文件系统。
同时,在管理文件系统时,我们也需要注意保护数据安全,并遵循相关规范和标准。
总之,在今后的学习和工作中,我将继续深入研究磁盘和文件系统管理相关知识,并不断提升自己的技能水平。
实验四 磁盘和文件系统管理心得
实验四磁盘和文件系统管理心得
实验四磁盘和文件系统管理心得
在本次实验中,我们学习了磁盘和文件系统的管理。
通过实验,我对磁盘和文件系统的概念及其管理方式有了更深入的了解和体验。
首先,磁盘管理是操作系统最基本的功能之一。
磁盘是计算机存储信息的主要设备,因此,对磁盘的管理显得尤为重要。
在实验中,我了解了磁盘的分区和格式化两个重要操作。
分区可以将一个大磁盘划分为多个逻辑分区,方便对不同的数据进行管理。
而格式化则是将分区或整个磁盘进行数据擦除,以便重新存储数据。
此外,我还学习了磁盘空间的管理,包括磁盘空间的容量、使用情况等,这些都是磁盘管理的重要内容。
其次,文件系统管理也是操作系统的重要功能之一。
文件系统是指计算机用来管理文件的一组规则和程序。
在实验中,我学习和掌握了文件的基本操作,如文件的创建、删除、拷贝和移动等。
同时,我还学习了文件系统的组成和结构,包括目录、文件描述符和索引节点等。
这些知识对文件系统的管理非常有帮助。
总之,通过本次实验,我深入了解了磁盘和文件系统的管理方式,掌握了它们的基本操作和原理,并且实践了相关操作。
这些知识对我今
后的计算机学习和工作都将有帮助。
实验4 文件系统模拟
实验4 文件系统模拟一、实验目的:设计和实现基于FAT12的模拟磁盘卷及其I/O系统的文件存取操作基本功能函数,深入领会和理解文件系统的体系结构、工作原理和设计要领。
二、实验设计1.根据FAT12设计模拟磁盘(1.44MB软盘映像文件)的磁盘组织结构及文件或空闲盘块管理方法与描述用数据结构,并实现模拟磁盘的创建和格式化操作。
2.设计和实现模拟磁盘I/O操作暨物理盘块与缓冲区(缓冲区与物理盘块大小相同)间数据交互的两个函数。
3.构建和提供用户与文件系统之间的基本接口,包括目录和文件的创建、重命名、删除和显示操作,目录的进入操作以及文件的定位及读、写操作。
4.测试系统功能并给出有效证据。
三、源程序清单和说明#include <stdio.h>#include <string.h>#include <stdlib.h>#define BlockSize 512#define DirSize 32#define RootSize 2struct ReserveBlock{int sysblocknum;/*文件系统总扇区数*/int resblocknum;/*保留扇区扇区数*/int fatblocknum;/*FA T表扇区数*/int rootblocknum;/*根目录区扇区数*/char fillchar[BlockSize-4*sizeof(int)];/*填充字节*/};struct DirBlock{char filename[11]; /*文件名限长11个字符*/charfillchar[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;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;}int CLOSESYS(FILE *stream){int i;fseek(stream,sys1.resblocknum*BlockSize,0);fwrite(fat1,sizeof(int)*sys1.sysblocknum,1,str eam);fseek(fp,(sys1.fatblocknum+sys1.resblocknum )*BlockSize,0);fwrite(dir,DirSize*32,1,fp);fclose(fp);return 1;}int FCREA TE(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("文件名过长\n");printf("请重新输入:");scanf("%s",filename);}elsebreak;}while(1){for(i=0;i<32;i++)if(strcmp(filename,fil[i].filename)==0){printf("该文件名已存在\n");printf("请重新输入:");flag1=1;break;}if(flag1==0)break;scanf("%s",filename);flag1=0;}for(i=(sys1.fatblocknum+sys1.resblocknum+s ys1.rootblocknum);i<sys1.sysblocknum;i++) if(fat1[i]==0)flag++;/*统计磁盘上为空数目*/if(flag==0){ printf("磁盘已满");/*统计结果为0,则磁盘已满*/return 0;}printf("空闲块数:%d\n",flag);printf("请输入文件长度:");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%Bl ockSize?1:0);if(n<0||n>flag)/*文件长度小于0或大于空闲的空间*/{printf("文件长度过长\n");printf("请重新输入:");}elsebreak;}for(i=(sys1.fatblocknum+sys1.resblocknum+s ys1.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;}elsefat1[m]=i+1;}m=i;}}strcpy(dir[j].filename,filename);dir[j].filename[a]='\0';printf("请输入年份:");scanf("%d",&dir[j].year);printf("请输入月份:");scanf("%d",&dir[j].month);printf("请输入日期:");scanf("%d",&dir[j].day);return (1);}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);}}}int FDELETE(char *filename)/*删除文件*/ {int i,j,k,n,flag=0;struct FCBBlock *p;/*文件控制块指针*/p=fcb;while(p){if(strcmp(filename,fil[p->fdtblockindex].filen ame)==0)/*目录项所在内序号*/{printf("文件已经打开,请先关闭文件\n");return 0;}elsep=p->next;}for(i=0;i<32;i++)/*查找要关闭的文件*/if(strcmp(filename,fil[i].filename)==0){ flag=1;break;}if(flag==0){printf("文件不存在\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;elsej=k;}memset(&fil[i],0,DirSize);return 1;}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("文件不存在\n");return 0;}while(p){j++;if(strcmp(filename,fil[p->fdtblockindex].filen ame)==0){printf("文件已打开\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;}long FGETLEN(int fileid)/*获取文件指针*/ { struct FCBBlock *p;p=fcb;while(p){if(p->fileid==fileid)/*寻找要找的指针*/return(p->filepos);p=p->next;}printf("error\n");return(0);}int FCLOSE(char *filename)/*关闭文件*/ { int flag=0;struct FCBBlock *f,*p;f=fcb;if(strcmp(filename,fil[fcb->fdtblockindex].file name)==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].filena me)==0){ flag=1;p=f->next;/*p=p->next;*/while(p){ p=p->next;p->fileid-=1;}free(f);return flag;}p=f;f=f->next;}if(flag==0){ printf("文件未打开\n'");return flag;}return 0;}int FREAD(char *str, int n, int fileid)/*文件块读*/{ int m,i,j=0,k,l,len;char a[3];struct FCBBlock *p;p=fcb;while(p){if(p->fileid==fileid)break;elsep=p->next;}len=fil[p->fdtblockindex].filelen;/*文件长度*/l=p->filepos;/*文件读写指针:该块在文件的相对位置*/printf("现在打开文件:");printf("%d\n",l);printf("是否读入这个文件?(Y/N):");scanf("%s",a);if(a[0]=='n'||a[0]=='N'){printf("输入内容:");while(1){scanf("%d",&l);if(fil[p->fdtblockindex].filelen<(l+n))/*?*/printf("too large!\ninput again:");elsebreak;}}while(1){if(n>fil[p->fdtblockindex].filelen){printf("too large!\n");printf("input read size,again:");scanf("%d",&n);}elsebreak;}str=(char*)malloc(fil[p->fdtblockindex].filelen+1);m=(len/BlockSize)+(len%BlockSize?1:0);k=fil[p->fdtblockindex].firstblockaddr;if(m>1){ fseek(fp,(k-1)*BlockSize,0);fread(str,BlockSize,1,fp);k=fat1[k-1];for(i=1;i<(m-1);i++){fseek(fp,fat1[k-1]*BlockSize,0);fread(&str[i*BlockSize],BlockSize,1,fp);k=fat1[k-1];}fseek(fp,(k-1)*BlockSize,0);fread(&str[i*BlockSize],len-i*BlockSize,1,fp);}else{ fseek(fp,(k-1)*BlockSize,0);fread(str,len,1,fp);}str[n+l]='\0';if(l!=0)str=&str[l];p->filepos=n+l;printf("%s\n",str);return 1;}void FWRITE(char *ptr, int n, int fileid){ char a[3];long l;int m,i=0,j,k=0,num,flag=0,flag1=0,b;struct FCBBlock *p;p=fcb;while(p){if(p->fileid==fileid)break;elsep=p->next;}l=p->filepos;printf("现在打开文件:");printf("%d\n",l);printf("是否写入这个文件?(Y/N):");scanf("%s",a);if(a[0]=='n'||a[0]=='N'){printf("输入内容:");while(1){scanf("%d",&l);if(fil[p->fdtblockindex].filelen<(l+n))printf("too large!\ninput again:");elsebreak;}}j=(l/BlockSize)+(l%BlockSize?1:0);if(l==0)j=1;num=fil[p->fdtblockindex].firstblockaddr;for(i=1;i<j;i++)num=fat1[num];do{if(flag==0){fseek(fp,(num-1)*BlockSize+l-(i-1)*BlockSi ze,0);flag=1;}else{fseek(fp,(num-1)*BlockSize,0);num=fat1[num-1];}if(((n+l)-(i-1)*BlockSize)>BlockSize ){if(flag1==0){fwrite(&ptr[0],j*BlockSize-l,1,fp);flag1=1;}else{fwrite(&ptr[j*BlockSize-l+k*BlockSize],Blo ckSize,1,fp);}}else{ m=j*BlockSize-l+(k-1)*BlockSize;b=n-(j*BlockSize-l+(k-1)*BlockSize);fwrite(&ptr[m],b,1,fp);}k++;i++;}while(((n+l)-(i-1)*BlockSize)>1);p->filepos=l+n;}int FEOF(int fileid){int flag;struct FCBBlock *p;p=fcb;while(p){if(p->fileid==fileid)break;}if(p->filepos>fil[p->fdtblockindex].filelen)return 0;elsereturn 1;}long FGETPOS(int fileid){struct FCBBlock *p;p=fcb;while(p){if(p->fileid==fileid)return (p->filepos);elsep=p->next;}printf("error!\n");return(0);}int FSETPOS(int fileid, long offset){struct FCBBlock *p;p=fcb;while(p){ if(p->fileid==fileid){ while(offset>fil[p->fdtblockindex].filelen||of fset<0){printf("set error!zhe pos >file length\n");printf("input file pos ,again:");scanf("%d",offset);}p->filepos=offset;return 1;}elsep=p->next;}printf("error!\n");return(0);}void DISPLAY(){printf("请输入命令:\n");printf("建立文件:creat\n");printf("显示目录:list\n");printf("删除文件:del\n");printf("打开文件:open\n");printf("关闭文件:close\n");printf("文件块读:read\n");printf("文件块写:write\n");printf("退出:exit\n");}void test(char *filename){char *t,cmd[10],fname[12];struct FCBBlock *p;int i,j,n,flag,len,id,flag1=0;fp=OPENSYS(filename);while(1){DISPLAY();scanf("%s",cmd);if(!strcmp(cmd,"creat")){printf("请输入文件名:\n");scanf("%s",fname);flag=FCREA TE(fname);if(flag==1)printf("文件%s 创建成功\n",fname);}else if(!strcmp(cmd,"list"))LISTDIR();else if(!strcmp(cmd,"del")){scanf("%s",fname);flag=FDELETE(fname);if(flag==1)printf("文件%s 删除成功\n",fname);}else if(!strcmp(cmd,"open")){scanf("%s",fname);flag=FOPEN(fname);if(flag==1)printf("文件%s 打开\n",fname);}else if(!strcmp(cmd,"close")){scanf("%s",fname);flag=FCLOSE(fname);if(flag==1)printf("文件%s 关闭\n",fname);}else if(!strcmp(cmd,"read")){scanf("%s",fname);p=fcb;flag1=0;while(p){ if(!strcmp(fil[p->fdtblockindex].filename,fn ame)){printf("请输入文件大小:");scanf("%d",&len);id=p->fileid;flag=FREAD(str,len,id);flag1=1;}p=p->next;}if(flag1==0)printf("文件%s 未打开,请先打开文件\n",fname);}else if(!strcmp(cmd,"write")){scanf("%s",fname);p=fcb;flag1=0;while(p){ if(!strcmp(fil[p->fdtblockindex].filename,fn ame)){printf("请输入文件大小:");do{scanf("%d",&len);if(len>fil[p->fdtblockindex].filelen)printf("文件长度过大,请重新输入:");}while(len>fil[p->fdtblockindex].fil elen);id=p->fileid;ptr=(char *)malloc(len);scanf("%s",ptr);FWRITE(ptr,len,id);flag1=1;}p=p->next;}if(flag1==0)printf("文件%s 未打开,请先打开文件\n",fname);}else if(!strcmp(cmd,"exit")){flag=CLOSESYS(fp);break;}elseprintf("error!\n");}}int main(void){ struct ReserveBlock sys;char filename[]="fatsys.dat";int *fat;int i,j;fcb=NULL;memset(&sys,255,BlockSize);printf("请输入索要创建的文件系统的大小(5~32767):");scanf("%d",&(sys.sysblocknum));sys.resblocknum=1;sys.fatblocknum=sys.sysblocknum/(BlockSize /sizeof(int))+((sys.sysblocknum%(BlockSize/sizeof(int)))?1 :0);fat=(int*)malloc(BlockSize*sys.fatblocknum);memset(fat,255,BlockSize*sys.fatblocknum);memset(fat,0,sizeof(int)*sys.sysblocknum);sys.rootblocknum=RootSize;j=sys.resblocknum+sys.fatblocknum+sys.root blocknum;for (i=0;i<j;i++)fat[i]=-1;memset(&fillchar,0,BlockSize);fp=fopen(filename,"w+b");fwrite(&sys,1,BlockSize,fp);for (i=0;i<sys.fatblocknum;i++)fwrite(fat+i*BlockSize/sizeof(int),1,BlockSize ,fp);j=sys.resblocknum+sys.fatblocknum;for(i=0;i<(sys.sysblocknum-j);i++)fwrite(&fillchar,1,BlockSize,fp);fclose(fp);free(fat);test(filename);return 0;}四、算法及关键数据结构设计1.模拟磁盘的格式化操作2.磁盘I/O操作模拟函数readBlock(int i, char *p);该函数把i#逻辑块的内容读入到指针p指向的盘块缓冲(注意读入计数处理)。
实验四文件系统实验
实验四文件系统实验一. 目的要求1、用高级语言编写和调试一个简单的文件系统,模拟文件管理的工作过程。
从而对各种文件操作命令的实质内容和执行过程有比较深入的了解。
2、要求设计一个n个用户的文件系统,每次用户可保存m个文件,用户在一次运行中只能打开一个文件,对文件必须设置保护措施,且至少有Create、delete、open、close、read、write等命令。
二. 例题:1、设计一个10个用户的文件系统,每次用户可保存10个文件,一次运行用户可以打开5个文件。
2、程序采用二级文件目录(即设置主目录[MFD])和用户文件目录(UED)。
另外,为打开文件设置了运行文件目录(AFD)。
3、为了便于实现,对文件的读写作了简化,在执行读写命令时,只需改读写指针,并不进行实际的读写操作。
4、算法与框图:①因系统小,文件目录的检索使用了简单的线性搜索。
②文件保护简单使用了三位保护码:允许读写执行、对应位为1,对应位为0,则表示不允许读写、执行。
③程序中使用的主要设计结构如下:主文件目录和用户文件目录(MFD、UFD)打开文件目录(AFD)(即运行文件目录)文件目录指针文件名··文件系统算法的流程图如下:三. 实验题:1、增加2~3个文件操作命令,并加以实现。
(如移动读写指针,改变文件属性,更换文件名,改变文件保护级别)。
代码如下://1、增加2~3个文件操作命令,并加以实现。
(如移动读写指针,改变文件属性,更换文件名,改变文件保护级别)。
#include<iostream>#include<string>#include<conio.h>using namespace std;struct TYPE_UFD{string File_Name;bool Read;bool Write;bool Execute;int Length_File;};struct TYPE_MFD{string User_Name;TYPE_UFD *Pointer;};struct TYPE_AFD{int File_ID;bool Read;bool Write;bool Execute;int Pointer;};class TYPE_FILE_SYSTEM{public:void Initial( void );void Start( void );private:int _Number_Users;int _Number_Files;int _MaxNumber_Open_Files;TYPE_MFD *_MFD;TYPE_UFD *_UFD;TYPE_AFD *_AFD;};void TYPE_FILE_SYSTEM::Initial( void ){_Number_Users = 10;_Number_Files = 10;_MaxNumber_Open_Files = 5;_UFD = new TYPE_UFD [_Number_Users*_Number_Files];_MFD = new TYPE_MFD [_Number_Users];int i=0;for( i=0 ; i<_Number_Users ; i++ ){_MFD[i].Pointer = &(_UFD[i*_Number_Files]);}_AFD = new TYPE_AFD [_MaxNumber_Open_Files];_MFD[0].User_Name = "zaq";_UFD[0].File_Name = "file1.txt";_UFD[0].Length_File = 10;_UFD[0].Read = true;_UFD[0].Write = false;_UFD[0].Execute = true;_UFD[1].File_Name = "file2.txt";_UFD[1].Length_File = 20;_UFD[1].Read = true;_UFD[1].Write = false;_UFD[1].Execute = false;for( i=2 ; i<_Number_Files ; i++ ){_UFD[i].File_Name = "";_UFD[i].Length_File = -1;_UFD[i].Read = false;_UFD[i].Write = false;_UFD[i].Execute = false;}}void TYPE_FILE_SYSTEM::Start( void ){int User_ID;int i,temp_int;string temp;char choice;int Number_Open_Files;string User_Name;string Command;TYPE_UFD *UFD;do{do{cout << "已创建用户名为zaq\n指令有:create delete open dir diropen write read logout shutdown \n\n";cout << "请输入用户名:";cin >> User_Name;for( User_ID=0 ; User_ID<_Number_Users ; User_ID++ ){if( _MFD[User_ID].User_Name == User_Name )break;}if( User_ID == _Number_Users )cout << "用户名错误,请再次输入." << endl;}while( User_ID == _Number_Users );cout << "欢迎登录, " << User_Name << " !" << endl;UFD = _MFD[User_ID].Pointer;for( i=0 ; i<_MaxNumber_Open_Files ; i++ ){_AFD[i].File_ID = -1;}Number_Open_Files = 0;do{cout << "C:\\" << User_Name << ">" ;cin >> Command;if( Command == "dir" ){cout << endl;cout << "打开用户" << User_Name <<"的文件" << endl;cout << "\t" << "State\t" << "Length\t" << "File name" << endl;for( i=0 ; i<_Number_Files ; i++ ){if( UFD[i].Length_File != -1 ){cout << "\t" ;if( UFD[i].Read == true )cout << "R";elsecout << "-";if( UFD[i].Write == true )cout << "W";elsecout << "-";if( UFD[i].Execute == true )cout << "E";elsecout << "-";cout << "\t";cout << UFD[i].Length_File;cout << "\t";cout << UFD[i].File_Name << endl;}}cout << endl;}else if( Command == "diropen" ){cout << endl;cout << "打开用户" << User_Name << "的文件"<<endl;cout << "\t" << "State\t" << "Open File name" << endl;for( i=0 ; i<_MaxNumber_Open_Files ; i++ ){if( _AFD[i].File_ID != -1 ){cout << "\t" ;if( _AFD[i].Read == true )cout << "R";elsecout << "-";if( _AFD[i].Write == true )cout << "W";elsecout << "-";if( _AFD[i].Execute == true )cout << "E";elsecout << "-";cout << "\t";cout << UFD[_AFD[i].File_ID].File_Name << endl;}}cout << endl;}else if( Command == "create" ){for( i=0 ; i<_Number_Files ; i++ )if( UFD[i].Length_File == -1 )break;if( i == _Number_Files )cout << "Error: 已有名为" << _Number_Files << " 的文件." << endl;else{cout << "请输入新文件信息:" << endl;cout << "文件名: ";cin >> temp;UFD[i].File_Name = temp;cout << "文件权限: ";cout << "Read (y/n):";do{choice = getch();}while( choice!='y' && choice!='n' );if( choice == 'y' )UFD[i].Read = true;elseUFD[i].Read = false;cout << endl;cout << "Write (y/n):";do{choice = getch();}while( choice!='y' && choice!='n' );if( choice == 'y' )UFD[i].Write = true;elseUFD[i].Write = false;cout << endl;cout << "Execute (y/n):";do{choice = getch();}while( choice!='y' && choice!='n' );if( choice == 'y' )UFD[i].Execute = true;elseUFD[i].Execute = false;cout << endl;cout << "Length :";cin >> temp_int;if( temp_int > 0 )UFD[i].Length_File = temp_int;cout << "新文件" << UFD[i].File_Name << " 已建立!" << endl;}}else if( Command == "delete" ){cout << "请输入文件名:";cin >> temp;for( i=0 ; i<_Number_Files ; i++ )if( (UFD[i].Length_File!=-1)&&(UFD[i].File_Name==temp) )break;if( i == _Number_Files )cout << "文件名错误,请再次输入." << endl;else{UFD[i].Length_File = -1;cout << "文件" << UFD[i].File_Name << " 已删除." << endl;}}else if( Command == "open" ){if( Number_Open_Files == _MaxNumber_Open_Files )cout << "Error: 你已经打开了" <<Number_Open_Files << " 文件." << endl;else{cout << "请输入文件名:";cin >> temp;for( i=0 ; i<_Number_Files ; i++ )if( (UFD[i].Length_File!=-1)&&(UFD[i].File_Name==temp) )break;if( i == _Number_Files )cout << "文件名错误,请再次输入." << endl;else{Number_Open_Files++;for( temp_int=0 ;temp_int<_MaxNumber_Open_Files ; temp_int++ )if( _AFD[temp_int].File_ID == -1 )break;_AFD[temp_int].File_ID = i;_AFD[temp_int].Pointer = 0;cout << "请定义打开方式:" << endl;if( UFD[i].Read == true ){cout << "Read (y/n):";do{choice = getch();}while( choice!='y' && choice!='n' );if( choice == 'y' )_AFD[temp_int].Read = true;else_AFD[temp_int].Read = false;cout << endl;}else_AFD[temp_int].Read = false;if( UFD[i].Write == true ){cout << "Write (y/n):";do{choice = getch();}while( choice!='y' && choice!='n' );if( choice == 'y' )_AFD[temp_int].Write = true;else_AFD[temp_int].Write = false;cout << endl;}else_AFD[temp_int].Write = false;if( UFD[i].Execute == true ){cout << "Execute (y/n):";do{choice = getch();}while( choice!='y' && choice!='n' );if( choice == 'y' )_AFD[temp_int].Execute = true;else_AFD[temp_int].Execute = false;cout << endl;}else_AFD[temp_int].Execute;cout << "文件" << temp << " 已打开." << endl;}}}else if( Command == "logout" ){cout << "再见, " << User_Name << " !" << endl;break;}else if( Command == "close" ){cout << "请输入文件名:";cin >> temp;for( i=0 ; i<_Number_Files ; i++ )if( (UFD[i].Length_File!=-1)&&(UFD[i].File_Name==temp) )break;if( i == _Number_Files )cout << "文件名错误,请再次输入." << endl;else{for( temp_int=0 ;temp_int<_MaxNumber_Open_Files ; temp_int++ )if( _AFD[temp_int].File_ID == i )break;if( temp_int == _MaxNumber_Open_Files )cout << "文件" << temp << " 未打开." << endl;else{_AFD[temp_int].File_ID = -1;Number_Open_Files--;cout << "文件" << temp << " 已关闭." << endl;}}}else if( Command == "read" ){cout << "请输入文件名:";cin >> temp;for( i=0 ; i<_Number_Files ; i++ )if( (UFD[i].Length_File!=-1)&&(UFD[i].File_Name==temp) )break;if( i == _Number_Files )cout << "文件名错误,请再次输入." << endl;else{for( temp_int=0 ;temp_int<_MaxNumber_Open_Files ; temp_int++ )if( _AFD[temp_int].File_ID == i )break;if( temp_int == _MaxNumber_Open_Files )cout << "文件" << temp << " 未打开." << endl;else{if( _AFD[temp_int].Read == true )cout << "文件" << temp << " 成功读取." << endl;elsecout << "Error: 文件打开模式错误." << endl;}}}else if( Command == "write" ){cout << "请输入文件名:";cin >> temp;for( i=0 ; i<_Number_Files ; i++ )if( (UFD[i].Length_File!=-1)&&(UFD[i].File_Name==temp) )break;if( i == _Number_Files )cout << "文件名错误,请再次输入." << endl;else{for( temp_int=0 ;temp_int<_MaxNumber_Open_Files ; temp_int++ )if( _AFD[temp_int].File_ID == i )break;if( temp_int == _MaxNumber_Open_Files )cout << "文件" << temp << " 未打开." << endl;else{if( _AFD[temp_int].Write == true )cout << "文件" << temp << " 成功写入." << endl;elsecout << "Error: 文件打开模式错误." << endl;}}}else if( Command == "shutdown" ){cout << "正在注销........" << endl;cout << "再见, " << User_Name << " !" << endl;cout << "正在关机.........." << endl;break;}else{cout << "指令错误,请再次输入." << endl;}}while( Command != "logout" && Command != "shutdown" );}while( Command != "shutdown" );}int main(){TYPE_FILE_SYSTEM FS;FS.Initial();FS.Start();return 0;}2、编一个通过屏幕选择命令的文件管理系统,每屏要为用户提供足够的选择信息,不需要打入冗长的命令。
实验四 操作系统_文件系统实验
1实验目的通过实验了解linux的文件系统结构。
通过练习使用linux命令查看文件系统信息;通过编程掌握文件操作函数使用。
2实验内容●学习通过linux命令查看文件系统信息状况●通过编程掌握文件系统调用操作3实验步骤3.1l inux文件及目录命令操作,熟悉常见linux文件操作命令,如:使用ls查看当前目录,使用cd改变当前工作目录,使用pwd 显示当前工作目录等3.2使用df、du命令查看文件系统及文件磁盘空间状况。
查阅资料简述命令输出包含哪些内容。
3.3使用ls –i及stat命令查看文件inod e信息,查阅资料简述stat命令输出包含哪些内容。
3.4文件系统创建3.5用dd 命令创建一个指定大小的文件(使用/dev/zero 作为源进行文件复制)3.5.1用mke2fs 在这个文件上创建一个文件系统,查阅资料总结mke2fs的功能说明,并简述输出所描述的信息。
3.5.2用dump2fs查看fs相关信息,查阅资料简述dump2fs的功能说明。
3.5.3使用od查看fs文件系统“磁盘”内容,并查阅ext2文件系统格式说明,了解其中的数据组成。
3.5.3.1查看超级快内容:od -tx1 -Ax fs -N1024 -j10243.5.3.2查看GDT块:od -tx1 -Ax fs -N1024 -j20483.5.3.3查看bl ock bitmap:od -tx1 -Ad fs -N1024 -j6144 查看inodebitmap:od -tx1 -Ad fs -N1024 -j71683.5.3.4查看inode tabl e:od -tx1 -Ad fs -N1024 -j8192查看databl ock:od -tx1 -Ad fs -N1024 -j245763.5.4使用mount 命令将新建的文件系统fs关联到一个回环设备后挂装到挂装点/mnt3.5.5在/mnt目录中创建子目录、文件后再使用dump2fs查看fs的free bl ocks等的信息变化或使用od命令查看信息变化。
实验4:文件系统管理与使用
实验4:Linux文件系统管理1、实验目的(1)掌握UNIX系统的文件系统结构及特点;(2)掌握Linux系统的目录结构和文件及目录管理命令;(3)掌握UNIX系统的存储设备和文件系统使用方法;(4)了解文件系统清理与同步。
2、实现设备一台装有Windows操作系统PC机,上装有虚拟机系统VMWare,实验过程通过VMWare 系统启Linux系统工作。
3、实验方法与注意事项实验室内的实验环境与系统是共用设施,请不要在系统内做对系统或对其他用户不安全的事情。
要求每个同学登录后系统后,要在自己的家目录内容以自己(拼音)名字或学号,创建一个子目录(已有者可以不再创建)。
以后所有工作都要在自己的目录内进行。
建议以后的实验都在同台计算机上做,这样可以保持连续性。
用户要按通常实验要认真书写实验报告。
4、实验过程(1)目录操作在当前目录下创建一个子目录,对其进行相应,然后再删除它(要求每步都要使用ls 命令观察结果):a. 创建目录:mkdir dir1 dir2b. 复制文件或目录:cp -r /etc/rc.d dir1c. 复制文件或目录:cp -r /etc/rc.d dir3d. 删除目录(方法1):rmdir dir1 dir2e. 删除目录(方法2):rm –rf dir1f. 观察dir3的内容后,删除之。
(2)文件的硬链接与符号链接创建一个文件myfile和一个目录mydir,分别为myfile创建一个硬链接和一个符号链接:ln myfile /tmp/myfile; ln -s myfile /tmp/myfile1ln -s mydir /tmp/myd使用ls命令查看结果。
(3)文件查找说明:如果查找的文件不存在,可以事先创建之,以供实验之用。
a. 在目录/tmp和/home下查找24小时内没有更改的文件。
find /tmp /home –mtime –1 –printb. 在/home下查找属于用户gjshao的c语言程序文件。
文件系统实验报告
试验四文件系统之蔡仲巾千创作一、二、实验目的1、用高级语言编写和调试一个简单的文件系统, 模拟文件管理的工作过程.从而对各种文件把持命令的实质内容和执行过程有比力深入的了解.2、要求设计一个n个用户的文件系统, 每次用户可以保管M个文件.用户在一次运行中只能翻开一个文件, 对文件必需设置呵护办法, 且至少有create、delete、open、close、read、write等命令.三、实验题目:采纳二级目录结构实现磁盘文件把持.要求:1.普通文件的目录项包括文件名, 文件类型, 文件长度, 指向文件内容的指针内容.2.目录文件的目录项包括目录名, 指向下一级目录块的指针内容.假定每个目录文件最多只能占用一个块;3.法式功能方面的要求:需要实现一个命令行把持界面, 包括如下命令:4.法式实现方面的要求:(1)、对重名(创立时), 文件不存在(删除时), 目录不存在(改变目录时)等毛病把持情况, 法式应该做出相应处置并给犯毛病信息, 可是法式不得因此而退出.(2)、界面友好, 法式强壮.(3)、设置界面的提示符, 提示的命令以及调试的方法应和前面的要求一致.不要自己设计命令或者附加不要求的功能.:执行文件名:Project1.exe四.实验分析1)总论:该系统是一个多用户、多任务的实时把持系统.对用户和用户的文件数目并没有上限.也就是说该系统允许任何用户申请空间, 而且在其目录下的文件数目其实不做任何的限制.该系统的把持命令如下:①、bye-用户注销命令.当使用该命令时, 用户退出系统.命令格式:run\bye↙系统注销该用户并回到登岸界面.②、close-删除用户注册信息命令.执行该命令后, 用户在系统中的所有信息, 包括该用户目录下的所有文件都被删除.命令格式:run\close↙.完成后返回登岸界面.③、create-在以后目录下创立一个文件, 且该文件不能跟系统中的文件重名.该文件的管理信息登录到用户文件信息管理模块中.命令格式:run\create>file1↙.其中file1为要创立的文件名称.执行完该命令后回到执行命令行.④、delete-删除以后用户目录下的一个文件.命令格式:run\delete>file1↙.返回命令行.⑤、list-显示以后注册目录下的所有文件信息, 包括文件名、文件长度、文件把持权限.命令格式:run\list↙.⑥、chmod-改变某个文件的执行权限, 但前提是该文件是该用户目录下的文件.命令格式:run\chmod>file1↙.⑦、open-在window界面下翻开某个文件.命令格:run\open>file1↙.执行该命令后, 文件file1将用在windows界面下的文件形式翻开.用户可以在这个方式中对文件进行修改, 并将修改后的内容保管.⑧、read-读文件信息.将文件信息读入并显示在终端.命令格式:run\read>file1↙.⑨、write-向某个文件写入新的信息.用户可以选择用覆盖原来内容的方式和在文件的末尾拔出新信息的方式写入信息. 2)_系统采纳二级文件目录.设置主目录(MFD)和用户文件目录(UFD), 分别以文件的方式保管在磁盘中.在主目录中又注册用户的用户名和另一标识表记标帜该用户目录下是否有文件的指针标识表记标帜.用户文件目录用用户名作为文件名保管在磁盘, 以便检索时方便对应.在用户文件目录中保管着该目录下所有的文件的文件名称、呵护码、文件长度. 3)该系统年夜量使用高级语言中的文件把持函数, 所以能实际看到文件的创立写入、读出、删除等效果.4) 实验流程图5)源法式:#include<iostream.h>#include<stdio.h> #include<stdlib.h> #include<string.h> #include "conio.h" #include<dos.h>#define NULL 0#define keynum 10#define getspace(type) (type*)malloc(sizeof(type))char cmd[64]; //寄存用户输入命令char buffer[36];//char user[32];//寄存以后登岸的用户名typedef char ALFA[12];ALFA KWORD[keynum];struct UFD{//用户文件管理模块char filename[32]; //文件名int safecode; //文件呵护码long length; //文件长度}*curfile = NULL;struct MFD{//用户登岸信息管理模块char username[32]; //用户名bool filepoint; //用户目录下的文件指针, false暗示目录为空}*curuser = NULL,*elseuser=NULL;typedef UFD UFD;typedef MFD MFD;void main();void KeyWord()//初始化命令关键字{strcpy(KWORD[ 1],"bye");strcpy(KWORD[ 2],"chmod");strcpy(KWORD[ 3],"close");strcpy(KWORD[ 4],"create");strcpy(KWORD[ 5],"delete");strcpy(KWORD[ 6],"list");strcpy(KWORD[ 7],"open"); strcpy(KWORD[ 8],"read");strcpy(KWORD[ 9],"write");}int LoginDisplay() //登岸选项把持函数{int SELETE_1 = 0;do{cout<<" *****请选择把持*****\n1、用户登岸 2、用户注册 0、退出"<<endl;cin>>SELETE_1;}while(SELETE_1<0 || SELETE_1>2);system("cls");return SELETE_1;}bool Login(int SELETE)//用户登岸, 注册函数{FILE *fp,*fp1,*fp2;char name[12];switch(SELETE){case 1://用户登岸if((fp = fopen("LOGIN.exe","rb")) == NULL)//翻开用户注册目录管理文件{cout<<"\n毛病:不能翻开登岸文件."<<endl;getch();system("cls");return false;}curuser = getspace(MFD);cout<<"\n*****登岸*****\n用户名:";cin>>name; //输入用户登岸名while(!feof(fp)) //检查该用户是否合法{fread(curuser,sizeof(MFD),1,fp);if(strcmp(curuser->username,name)==0)break;}if(feof(fp)) //如果没有找到跟以后登岸用户名相同的管理信息, 提示犯错{cout<<"\n毛病:该用户不存在."<<endl;fclose(fp);return false;}else{fclose(fp);return true;}break;case 2: //新用户注册if((fp=fopen("LOGIN.exe","ab"))==NULL)//如果登岸信息管理文件不存在fp=fopen("LOGIN.exe","wb+"); //创立该信息管理文件char name[12];curuser = getspace(MFD);while(1){cout<<"\n *****新用户注册*****"<<endl;cout<<"用户名:";cin>>name; //输入用户注册名fp1 = fopen("LOGIN.exe","rb");while(!feof(fp1))//检查该用户名是否被另外用户占用{fread(curuser,sizeof(MFD),1,fp1);if(strcmp(curuser->username,name) == 0)//该名称已经被使用{cout<<"\n该用户已经存在, 请重新输入!"<<endl;getch();break;}}if(feof(fp1))//该名称没有被另外用户占用{strcpy(curuser->username,name);curuser->filepoint = NULL;fwrite(curuser,sizeof(MFD),1,fp);strcpy(user,curuser->username);//生成用户文件管理模块strcat(user,".exe"); //用于管理用户目录下的各个文件fp2=fopen(user,"wb+");fclose(fp2);cout<<"\n注册胜利!"<<endl; //提示注册胜利fclose(fp1);fclose(fp);break;}}fp = fopen("LOGIN.exe","rb"); //显示以后注册用户的名称while(1){fread(curuser,sizeof(MFD),1,fp);if(feof(fp))break;cout<<curuser->username<<endl;getch();}fclose(fp);return true;break;default:return false;break;}}void DisplayUFD()//打印用户信息, 包括用户的各个文件//名称、长度和把持权限的设置信息{if(curuser->filepoint == false)//以后用户目录下没有任何文件存在cout<<"\n用户 "<<curuser->username<<" 文件夹是空的"<<endl;else{//存在文件, 将所有文件信息打印在终端FILE *fp;char filename[12];strcpy(filename,curuser->username);strcat(filename,".exe");if((fp=fopen(filename,"rb"))==NULL)//翻开用户文件信息管理模块{cout<<"\n无法翻开用户:"<<curuser->username<<" 的文件!"<<endl;getch();return;}else{//读入并将用户全部文件信息打印在终端cout<<"用户:"<<curuser->username<<"目录下的文件:"<<endl;UFD *ufd;int i=0;ufd = getspace(UFD); //申请寄存用户文件模块的空间while(1){fread(ufd,sizeof(UFD),1,fp);if(feof(fp))//全部输出完毕, 结束break;else//打印信息cout<<ufd->filename<<"\t"<<ufd->length<<"\t"<<ufd->safecode<<endl;}}fclose(fp);}}void ByeFile(bool BOOL)//注销函数, 调用次函数用户可以退出系统{FILE *infile,*outfile;char out[50];strcpy(out,"outfilelocate.exe");if((infile=fopen("LOGIN.exe","rb"))==NULL){cout<<"\n保管毛病."; // fclose(infile);return;}else{if((outfile=fopen(out,"wb+"))==NULL)//申请一个缓冲区管理模块//寄存用户更新后的全部信息{cout<<"\n保管毛病.";// fclose(outfile);fclose(infile);return;}else{MFD *mfd = getspace(MFD);while(1){//将旧文件管理信息读出, 并保管到新的文件信息管理模块中fread(mfd,sizeof(MFD),1,infile);if(feof(infile))break;if((strcmp(mfd->username,curuser->username))==0){if(BOOL)//更新以后用户信息的把持fwrite(curuser,sizeof(MFD),1,outfile);else continue;//如果用户想把自己的注册目录从系统中完全删除//则执行该把持}elsefwrite(mfd,sizeof(MFD),1,outfile);//写入新的模块}fclose(infile);fclose(outfile);remove("LOGIN.exe");//将旧的该用户的文件管理模块删除rename(out,"LOGIN.exe");//将新的用户的文件管理模块重命名为用户目录下的管理模块}}system("cls");main();}bool ClearUserFile()//用户要将自己的注册目录从系统完全删除//首先将该用户目录下的全部文件删除{FILE *fp;char file[50];strcpy(file,curuser->username);strcat(file,".exe");if((fp=fopen(file,"rb"))==NULL) //翻开用户文件信息管理模块{// fclose(fp);cout<<"\n把持失败.";return true;}else{//将该用户目录下的文件逐个从磁盘删除UFD *ufd = getspace(UFD);while(1){fread(ufd,sizeof(UFD),1,fp);if(feof(fp))break;elseremove(ufd->filename);//删除文件}fclose(fp);return true;}}void ClearUserMes()//删除用户全部信息{char name[50];strcpy(name,curuser->username);strcat(name,".exe");remove(name); //从磁盘中删除用户文件信息管理模块ByeFile(false);//更新系统的用户登岸信息管理模块}void DeleteUser()//删除用户注册目录的把持{char ch;cout<<"\n该把持将会是你在系统所有信息删除, 下次登岸时你必需重新申请用户名!"<<endl;cout<<"\n你确定要删除你在系统中的注册信息吗?Y/N"<<endl;cin>>ch;switch(ch)//提示用户确认删除{case 'Y':case 'y':if(ClearUserFile())//如果用户的全部文件已经删除//则可以将该用户的文件信息管理模块也从磁盘中删除//以免在没完全删除文件却删了该文件信息管理模块//使得这些文件无法再进行管理造成磁盘空间的浪费ClearUserMes();//删除文件信息管理模块break;default:cout<<"\n你取消了此把持!";break;}}void CreatFile()//在以后用户目录下创立文件{FILE *fp;curuser->filepoint=true;if((fp=fopen(buffer,"r"))==NULL)//如果没有跟用户输入文件名相同的文件{if((fp=fopen(buffer,"w"))==NULL){cout<<"\n创立文件失败!";// fclose(fp);return;}fclose(fp);}else{//用户要创立的文件已经存在cout<<"\n该文件已经存在, 创立另一个文件?Y/N";char ch;cin>>ch;switch(ch){case 'Y':case 'y':cout<<"\n输入新文件名:";cin>>buffer;strcat(buffer,".txt");fclose(fp);if((fp=fopen(buffer,"w"))==NULL){cout<<"\n创立文件失败!";// fclose(fp);return;}fclose(fp);break;default:fclose(fp);return;}}strcpy(user,curuser->username);strcat(user,".exe");curfile = getspace(UFD);strcpy(curfile->filename,buffer);//文件名curfile->length=0; //该文件长度为零curfile->safecode=30; //设置该文件的默认权限//11 00, 文件主有读和写权, 其他用户没有读写权if((fp=fopen(user,"ab"))==NULL){cout<<"\n毛病:你可能不是合法用户."<<endl;getch();}else{fwrite(curfile,sizeof(UFD),1,fp);//将该文件信息写入用户文件信息管理模块中cout<<"\n文件"<<curfile->filename<<" 创立胜利!";}fclose(fp);}void DeleteFile()//删除以后目录下一个文件的把持{char ch;FILE *infile,*outfile;cout<<"\n确定要删除文件:"<<buffer<<" Y/N"<<endl;cin>>ch;//提示用户确认删除switch(ch){case 'Y':case 'y'://更新用户文件信息管理模块, 这里同样使用缓冲区模块来更新//方法与上面将到的类似char out[50],in[50];strcpy(out,"outfilelocate.exe");strcpy(in,curuser->username);strcat(in,".exe");if((infile=fopen(in,"rb"))==NULL)//翻开该用户的文件信息管理模块{cout<<"\n保管毛病.";//fclose(infile);return;}else{if((outfile=fopen(out,"wb+"))==NULL){cout<<"\n保管毛病.";// fclose(outfile);fclose(infile);return;}else{UFD *ufd = getspace(UFD);while(1){fread(ufd,sizeof(UFD),1,infile);//从旧模块读出信息if(feof(infile))break;if((strcmp(ufd->filename,buffer))==0)//要进行更新的信息continue;elsefwrite(ufd,sizeof(UFD),1,outfile);//写入新模块}fclose(infile);fclose(outfile);remove(in);//在磁盘移除就模块rename(out,in); //新模块命名为以后用户文件信息管理模块}}remove(buffer);//从磁盘中删除该文件break;default:break;}}void ListAllFile()//显示以后用户目录下的文件信息{DisplayUFD();}void OpenFile()//在window模式下翻开该文件{}bool QueryModElse(bool BOOL,bool &flag)//查询其它用户目录下文件的文件//当该文件的权限允许以后用户对其执行有关把持时, 返回ture {FILE *fp;char user[50];UFD *ufd = getspace(UFD);//elseuser暗示除以后用户外的所有用户注册目录strcpy(user,elseuser->username);strcat(user,".exe");if((fp=fopen(user,"rb"))==NULL){//翻开一个其它的用户文件信息管理模块// fclose(fp);cout<<"\n把持呈现毛病, 对此我们暗示歉意!";return false;}else{while(1){fread(ufd,sizeof(UFD),1,fp);if(feof(fp)){fclose(fp);return false;}if(strcmp(ufd->filename,buffer)==0){if(BOOL)//该用户请求写该文件{if(ufd->safecode== 31 || ufd->safecode== 33)//1101、1111最后一位为1, 有写权return true;else{cout<<"\n你无权对文件"<<buffer<<" 执行此把持!";flag=true;return false;}//flag设置为true, 告诉上一层, 无须再查找//该文件已经找到, 但用户无权执行相关把持}else //该用户请求读权{if(ufd->safecode == 32 || ufd->safecode == 33)//1110、1111倒数第二位为1, 有读权return true;else{cout<<"\n你无权对文件"<<buffer<<" 执行此把持!";flag=true;return false;}}}}}}bool QueryMod(bool BOOL)//查询权限{//首先在用户目录下查找, 如果找不到用户以后要进行把持的文件名//则在其它注册用户目录下查找FILE *fp,*fp1;bool flag=false;char user[50];UFD *ufd = getspace(UFD);strcpy(user,curuser->username);strcat(user,".exe");if((fp=fopen(user,"rb"))==NULL){//翻开用户文件信息管理模块// fclose(fp);cout<<"\n把持呈现毛病, 对此我们暗示歉意!";return false;}else{//查找匹配的文件名, 用户目录下的文件允许用户进行读写把持while(1){fread(ufd,sizeof(UFD),1,fp);if(feof(fp)){//在以后用户文件管理模块中找不到匹配文件//则继续在其它用户注册目录下查找fclose(fp);fp1=fopen("LOGIN.exe","rb");elseuser = getspace(MFD);bool BOOL_1=false;while(1){fread(elseuser,sizeof(MFD),1,fp1);//读其它用户信息if(feof(fp1) && !BOOL_1)//全部用户都查找完//但仍然没找到匹配的文件return false;if(elseuser != curuser){if((BOOL_1=QueryModElse(BOOL,flag)))//查找return true;if(flag)return false;}}}if(strcmp(ufd->filename,buffer)==0){//在以后用户注册目录下//找到该文件, 返回真值fclose(fp);return true;}}}}bool WriteRight(int len,bool BOOL)//检查是否已经正确地写入到该文件信息中//是则返回真值{char user[50],outfile[50];FILE *fp,*fp1;strcpy(user,elseuser->username);strcat(user,".exe");if((fp=fopen(user,"rb"))==NULL){return false;}else{UFD *ufd = getspace(UFD);while(1){//在此用户目录下查找匹配文件fread(ufd,sizeof(UFD),1,fp);if(feof(fp)){fclose(fp);return false;}if((strcmp(ufd->filename,buffer))==0){//找到要写入新的长度的文件strcpy(outfile,"outfilelocate.exe");if((fp1=fopen(outfile,"wb+"))==NULL){cout<<"\n毛病:写入文件长度犯错_3.";// fclose(fp1);fclose(fp);return false;}else{fclose(fp);fp=fopen(user,"rb");//文件指针重新指向此用户文件信息管理模块开头while(1){fread(ufd,sizeof(UFD),1,fp);if(feof(fp))break;if(strcmp(ufd->filename,buffer)==0){//找到匹配的文件if(BOOL) ufd->length+=len; //在文件末追加内容的把持else ufd->length =len;//覆盖原文件内容}fwrite(ufd,sizeof(UFD),1,fp1);}fclose(fp);fclose(fp1);remove(user);rename(outfile,user);return true;}}}}}void WriteLengthToFile(int Len,bool BOOL)//将文件长度写入文件管理模块中{//因为以后用户可以对其它用户的文件进行把持(只要权限允许)//所以应该在整个文件系统目录下查找该文件的位置FILE *fp;if((fp=fopen("LOGIN.exe","rb"))==NULL){//不能翻开文件cout<<"\n写入文件长度毛病_1!";// fclose(fp);return;}else{elseuser = getspace(MFD);while(1){fread(elseuser,sizeof(MFD),1,fp);if(feof(fp))break;else{if(WriteRight(Len,BOOL)){//检查是否已经正确地写入到该文件信息中fclose(fp);return;}}}cout<<"\n写入文件长度毛病_2!";fclose(fp);return;}}void WriteFile()//向文件写入信息的把持{if(!QueryMod(true))//查询以后用户对该文件是否有写权return;//对该文件没有写权则返回char ch;int i=0;FILE *fp;if((fp=fopen(buffer,"r"))==NULL)//查询该文件是否存在{cout<<"\n该文件不存在, 请创立该文件后再写入.";// fclose(fp);return;}fclose(fp);cout<<"\n请选择写入方式:"<<endl;cout<<" 1、覆盖原文件 2、在原文件末尾写入 3、取消"<<endl;cin>>ch;cout<<"开始输入正文:"<<endl;switch(ch){case '1'://覆盖原文件if((fp=fopen(buffer,"w"))==NULL)cout<<"\n文件翻开失败.";else{ch=getchar();while(ch!='#')//将新的文件内容写入到文件的磁盘位置中{i++;fputc(ch,fp);ch=getchar();}}fclose(fp);WriteLengthToFile(i,false);//将文件长度写入文件管理模块break;case '2':if((fp=fopen(buffer,"a"))==NULL)cout<<"\n文件翻开失败.";else{ch=getchar();while(ch!='#')//将新的文件内容写入到文件的磁盘位置中{i++;fputc(ch,fp);ch=getchar();}}fclose(fp);WriteLengthToFile(i,true);//将文件长度写入文件管理模块break;default:break;}}void ReadFile()//读文件函数{if(!QueryMod(false))//查询以后用户是否有权读该文件return;//没有读权, 则返回FILE *fp;if((fp=fopen(buffer,"r"))==NULL)//翻开该文件{cout<<buffer;cout<<"\n该文件不存在.";return;}else{char ch;ch=fgetc(fp);while(ch!=EOF)//将该文件信息逐一输出到终端{putchar(ch);ch=fgetc(fp);}cout<<endl;}fclose(fp);}void ChangeMod()//修改某文件的执行权限{int mod=40;FILE *fp,*infile,*outfile;char in[50],out[50];UFD *ufd = getspace(UFD);strcpy(in,curuser->username);strcat(in,".exe");strcpy(out,"outfilelocate.exe");if((fp=fopen(in,"rb"))==NULL){// fclose(fp);cout<<"\n把持呈现毛病, 对此我们暗示歉意!";return;}else{while(1){//检查该文件是否在以后用户的注册目录下//任何用户无权修改不是自己目录下的文件的权限值fread(ufd,sizeof(UFD),1,fp);if(feof(fp)){//在以后目录下找不到该文件, 说明该用户无权修改该文件权限cout<<"\n你没有权限对文件"<<buffer<<" 执行该把持!";fclose(fp);return;}if(strcmp(ufd->filename,buffer)==0){//找到该文件, 继续把持fclose(fp);break;}}}bool flag1=true;while(flag1){cout<<"\n输入文件 "<<buffer<<" 的新的权限值:";cin>>mod;//输入权限值if(mod<30 || mod>33){//确保输入的权限值正确cout<<"\n毛病:权限值必需在30~33之间";continue;}else{char ch;switch(mod){//告诉用户对该文件权限修改的结果, 以便用户确认case 30:cout<<"\n以后权限设置:其他用户对"<<buffer<<"既没读权也没写权!";break;case 31:cout<<"\n以后权限设置:其他用户对"<<buffer<<"没读权但有写权!";break;case 32:cout<<"\n以后权限设置:其他用户对"<<buffer<<"有读权但没写权!";break;case 33:cout<<"\n以后权限设置:其他用户对"<<buffer<<"既有读权也有写权!";break;default: break;}cout<<"\n确认按'Y', 取消按'N':";cin>>ch;switch(ch){case 'Y':case 'y':flag1=false;break;default: flag1=true;}}}//更新文件信息管理模块, 相关把持类似上面, 不在赘述if((infile=fopen(in,"rb"))==NULL){cout<<"\n把持呈现毛病, 对此我们暗示歉意!";fclose(infile);return;}else{if((outfile=fopen(out,"wb+"))==NULL){cout<<"\n把持呈现毛病, 对此我们暗示歉意!";fclose(infile);//fclose(outfile);return;}else{while(1){fread(ufd,sizeof(UFD),1,infile);if(feof(infile))break;if((strcmp(ufd->filename,buffer))==0)ufd->safecode=mod;fwrite(ufd,sizeof(UFD),1,outfile);}fclose(infile);fclose(outfile);remove(in);rename(out,in);}}}void Execute(int i,int len,int cmdset)//执行命令函数{int j=0;for(;i<len;i++){if(cmd[i]=='>'||cmd[i]==' ')break;buffer[j]=cmd[i];j++;}buffer[j]='\0';strcat(buffer,".txt");switch(cmdset){case 1: //退出ByeFile(true);break;case 2: //改变文件把持权限if((strcmp(buffer,".txt"))==0){cout<<"\n输入命令犯错!";return;}ChangeMod();break;case 3: //删除用户DeleteUser();break;case 4: //创立文件if((strcmp(buffer,".txt"))==0){cout<<"\n输入命令犯错!";return;}CreatFile();break;case 5: //删除文件if((strcmp(buffer,".txt"))==0){cout<<"\n输入命令犯错!";return;}DeleteFile();break;case 6: //列出该用户所有文件清单ListAllFile();break;case 7: //翻开文件if((strcmp(buffer,".txt"))==0){cout<<"\n输入命令犯错!";return;}OpenFile();break;case 8: //读文件if((strcmp(buffer,".txt"))==0){cout<<"\n输入命令犯错!";return;}ReadFile();break;case 9: //写文件if((strcmp(buffer,".txt"))==0){cout<<"\n输入命令犯错!";return;}WriteFile();break;default:break;}}void Command()//读取用户输入的命令, 并将其转换成系统能识另外命令{int len = 0,i,j;int cmdset;while(1){cmdset = 0;cout<<"\nrun\\";cin>>cmd;len = strlen(cmd);i=0;j=0;while(cmd[i]=='>'||cmd[i]==' '){i++;}//过滤空格键和'>'for(;i<len;i++){if(cmd[i]=='>' || cmd[i]==' ' || i==len-1){if(cmd[i]=='>' || cmd[i]==' ')buffer[j] = '\0';elseif(i==len-1){buffer[j]=cmd[i];buffer[j+1]='\0';}i++;j=0;int low=1,mid,high=keynum-1;bool BOOL = false;while(low<=high){//找到该命令关键字的内部识别码mid=(low+high)/2;if (strcmp(buffer,KWORD[mid])<=0) high=mid-1;if (strcmp(buffer,KWORD[mid])>=0) low=mid+1;if(strcmp(buffer,KWORD[mid])==0){BOOL = true;break;}}if(!BOOL){cout<<"\n"<<buffer<<"不是系统界说的命令...";cmdset = 0; break;}else {cmdset = mid;break;}}else{buffer[j] = cmd[i];j++;}}if(cmdset == 0) continue;while(cmd[i]=='>'||cmd[i]==' '){i++;}//过滤空格键和'>'buffer[0]='\0';Execute(i,len,cmdset); //执行该命令}}void main(){while(1){int SELETE = LoginDisplay();if(SELETE==0)exit(0);bool BOOL = Login(SELETE);//用户登岸, 或者注册函数if(BOOL){KeyWord(); //初始化命令关键字DisplayUFD();//打印用户目录下的文件Command(); //命令行把持}}}五.调试结果:1)系统界面如下:2)创立新用户:如果你以前还没有注册,则可以先选择2,创立一个用户.3)创立用户后,可以用create>xiao命令建立一个名为xiao的text文件.并可以用list检查文件的信息(xiao.txt是文件名, 0暗示文件以后的长度为0, 30用二进制暗示为1100, 暗示以后用户有读写权, 而其它用户没有读权也没有写权).4)用write>xiao命令向这个文件写信息,选择1或是2,输入信息如下: (注意:所有信息输入完后要以‘#’号键作为结束标识表记标帜.)5)用read>xiao命令读文件中的内容.6)此时再write>xiao命令向这个文件写信息,选择1,输入信息,并用read>xiao检查,结果如下:7)还可以用open>xiao这个命令翻开文件,发现文件内容酿成:8)以上是文件的基本把持,要理解这个系统的更多功能,用户只需亲自使用这个界面友好,提示众多的软件几分钟,就可以很自由的把持这个软件了.所以这里就纷歧一介绍了.:此次实验做的比力全面,编译也是用C++builder.主要是因为把持系统的课程设计也是类似的文件系统管理,可重新做类似的事,兴趣没有这么高了,不外还是有新的收获的.。
实验四文件系统实验
实验四文件系统实验1)掌握文件系统的工作机理。
2)理解文件系统的主要数据结构。
3)学习较为复杂的LINU某下的编程实验内容设计并实现一个一级(单用户)文件系统程序a.提供以下操作:文件创建/删除接口命令create/delete目录创建/删除接口命令mkdir/rmdir显示目录内容命令lb.创建的文件不要求格式和内容2)设计并实现一个二级文件系统程序a.提供用户登录;b.文件、目录要有权限实验结果及其解释说明基本上实现了简单文件系统的实现。
创建并读写文件如下图所示:打开文件、关闭文件、创建并显示子目录、删除子目录如下图所示:实验中的问题及解决首先应确定文件系统的数据结构:主目录、子目录及活动文件等。
主目录和子目录都应以文件的形式存放于磁盘,这样便于查找和修改。
由于对文件系统理解不够深刻,导致程序在一些原理上的迷糊不清,而时间较短,因此采取了简化的方法。
在写程序的开始也没有做详细的规划,因此在程序的结构上有些混乱。
在后期做了一些调整,但是整体还是有缺陷的。
另外程序只是很简单的实现了文件管理系统,只有一些非常简单的功能,而且功能考虑的也不尽全面、严谨,难免会出现一些Bug。
必须对写好的程序进行反复的调试和优化。
实验体会程序清单#include#include#include#defineDIR_LENGTH1024/某路径最长可达100字节某/#defineMA某_WRITE1024某128/某写入文字可达128k字节某/#defineMEM_D_SIZE1024某1024/某1M磁盘空间某/#defineDISKSIZE1024/某磁盘快的大小1K某/#defineMSD5/某最大子目录数5(类似五叉树)某/#defineDISK_NUMMEM_D_SIZE/DISKSIZE/某磁盘快数目1024=1M/1K某/#defineFATSIZEDISK_NUM某izeof(tructfatitem)/某FAT表大小8K=8192B(理想应该是1.5K)某/#defineMOFN5/某最大文件打开数5(即除根以外最大深度为5)某/#defineROOT_DISK_NOFATSIZE/DISKSIZE+1/某根目录起始盘快号9某/#defineROOT_DISK_SIZEizeof(tructdirect)/某根目录大小196某/ /某---------------FAT表项结构-----------------------某/tructfatitem/某ize8某/{intitem;/某存放文件下一个磁盘的指针某/charem_dik;/某磁盘块是否空闲标志位0空闲某/};/某-------------------目录项结构------------------------某/tructdirect/某ize196某/{/某-----文件控制快信息-----某/tructFCB{charname[9];/某文件/目录名8位某/charproperty;/某属性1位目录0位普通文件某/intize;/某文件/目录字节数(原注释位盘块数)某/intfirtdik;/某文件/目录起始盘块号某/intne某t;/某子目录起始盘块号某/intign;/某1是根目录0不是根目录某/}directitem[MSD+2];};/某------------------文件打开表项结构--------------------------某/tructopentable/某ize104某/{tructopenttableitem/某ize20某/{charname[9];/某文件名某/intfirtdik;/某起始盘块号某/intize;/某文件的大小某/}openitem[MOFN];intcur_ize;/某当前打文件的数目某/};/某-------------------------------------------------------------------某/tructfatitem某fat;/某FAT表某/tructdirect某root;/某根目录某/tructdirect某cur_dir;/某当前目录某/tructopentableu_opentable;/某文件打开表某/intfd=-1;/某文件打开表的序号某/char某bufferdir;/某记录当前路径的名称某/char某fdik;/某虚拟磁盘起始地址某/voidinitfile();voidformat();voidenter();voidhalt();intcreate(char某name);intopen(char某name);intcloe(char某name);intwrite(intfd,char某buf,intlen);intread(intfd,char某buf);intdel(char某name);intmkdir(char某name);intrmdir(char某name);voiddir();intcd(char某name);voidprint();voidhow();/某----------------------------------------------------------------------------------------------某//某------------------------------------------初始化文件系统--------------------------------------某/voidinitfile(){ fdik=(char某)malloc(MEM_D_SIZE某izeof(char));/某申请1M空间某/format();free(fdik);}/某----------------------------------------------------------------------------------------------某//某------------------------------------------格式化----------------------------------------------某/voidformat(){inti;FILE某fp;fat=(tructfatitem某)(fdik+DISKSIZE);/某计算FAT表地址(为什么向后偏移1k)某//某-----初始化FAT表------------某/fat[0].item=-1;/某引导块某/fat[0].em_dik='1';for(i=1;ifat[i].item=i+1;fat[i].em_dik='1';}fat[ROOT_DISK_NO-1].item=-1;fat[ROOT_DISK_NO-1].em_dik='1';fat[ROOT_DISK_NO].item=-1;/某存放根目录的磁盘块号某/fat[ROOT_DISK_NO].em_dik='1';for(i=ROOT_DISK_NO+1;ifat[i].item=-1;fat[i].em_dik='0';}/某-----------------------------------------------某/root=(tructdirect某)(fdik+DISKSIZE+FATSIZE);/某根目录的地址某//某初始化目录某//某---------指向当前目录的目录项---------某/root->directitem[0].ign=1;root->directitem[0].firtdik=ROOT_DISK_NO;trcpy(root->directitem[0].name,\root->directitem[0].ne某t=root->directitem[0].firtdik;root->directitem[0].property='1';root->directitem[0].ize=ROOT_DISK_SIZE;/某-------指向上一级目录的目录项---------某/root->directitem[1].ign=1;root->directitem[1].firtdik=ROOT_DISK_NO;trcpy(root->directitem[1].name,\root->directitem[1].ne某t=root->directitem[0].firtdik;root->directitem[1].property='1';root->directitem[1].ize=ROOT_DISK_SIZE;for(i=2;iroot->directitem[i].ign=0;root->directitem[i].firtdik=-1;trcpy(root->directitem[i].name,\root->directitem[i].ne某t=-1;root->directitem[i].property='0';root->directitem[i].ize=0;} if((fp=fopen(\{printf(\return;}if(fwrite(fdik,MEM_D_SIZE,1,fp)!=1)/某把虚拟磁盘空间保存到磁盘文件中某/{printf(\}fcloe(fp);}/某----------------------------------------------------------------------------------------------某//某--------------------------------进入文件系统--------------------------------------------------某/voidenter(){FILE某fp;inti;fdik=(char某)malloc(MEM_D_SIZE某izeof(char));/某申请1M空间某/if((fp=fopen(\{printf(\return;}if(!fread(fdik,MEM_D_SIZE,1,fp))/某把磁盘文件dik.dat读入虚拟磁盘空间(内存)某/{printf(\e某it(0);}fat=(tructfatitem某)(fdik+DISKSIZE);/某找到FAT表地址某/root=(tructdirect某)(fdik+DISKSIZE+FATSIZE);/某找到根目录地址某/fcloe(fp);/某--------------初始化用户打开表------------------某/for(i=0;itrcpy(u_opentable.openitem[i].name,\u_opentable.openitem[i]. firtdik=-1;u_opentable.openitem[i].ize=0;}u_opentable.cur_ize=0;cur_dir=root;/某当前目录为根目录某/bufferdir=(char某)malloc(DIR_LENGTH某izeof(char));trcpy(bufferdir,\显示根目录为E:某/}-------------------------------------某//某------------------------------------退出文件系统----------------------------------------------某/voidhalt(){FILE某fp;inti;if((fp=fopen(\{printf(\return;}if(!fwrite(fdik,MEM_D_SIZE,1,fp))/某把虚拟磁盘空间(内存)内容读入磁盘文件dik.dat某/{printf(\}fcloe(fp);free(fdik);free(bufferdir);for(i=0;itrcpy(u_opentable.openitem[i].name,\u_opentable.openitem[i]. firtdik=0;u_opentable.openitem[i].ize=0;}u_opentable.cur_ize=0;/某用户打开文件数清零某/return;}-------------------------------------某//某----------------------------------------创建文件----------------------------------------------某/intcreate(char某name){inti,j;if(trlen(name)>8)/某文件名大于8位某/return(-1);for(i=2;iif(cur_dir->directitem[i].firtdik==-1)break;}for(j=2;j{if(!trcmp(cur_dir->directitem[j].name,name))break;}if(i>=MSD+2)/某无空目录项某/return(-2);if(u_opentable.cur_ize>=MOFN)/某打开文件太多(第五层)某/return(-3);if(jfor(j=ROOT_DISK_NO+1;jif(fat[j].em_dik=='0')break;}if(j>=DISK_NUM)return(-5);fat[j].em_dik='1';/某将空闲块置为已经分配某//某-----------填写目录项-----------------某/trcpy(cur_dir->directitem[i].name,name);cur_dir->directitem[i].firtdik=j;cur_dir->directitem[i].ize=0;cur_dir->directitem[i].ne某t=j;cur_dir->directitem[i].property='0';/某cur_dir->directitem[i].ign丢失某//某---------------------------------某/fd=open(name);/某打开所创建的文件某/return0;}/某----------------------------------------------------------------------------------------------某//某----------------------------------------打开文件----------------------------------------------某/intopen(char某name){inti,j;for(i=2;iif(!trcmp(cur_dir->directitem[i].name,name))break;}if(i>=MSD+2)/某文件不存在某/return(-1);/某--------是文件还是目录-----------------------某/if(cur_dir->directitem[i].property=='1')/某是目录,不可打开读写某/return(-4);/某--------文件是否打开-----------------------某/for(j=0;j if(!trcmp(u_opentable.openitem[j].name,name))break;}if(jif(u_opentable.cur_ize>=MOFN)/某文件打开太多某/return(-3);/某--------查找一个空闲用户打开表项-----------------------某/for(j=0;jif(u_opentable.openitem[j].firtdik==-1)break;}/某--------------填写表项的相关信息------------------------某/u_opentable.openitem[j].firtdik=cur_dir->directitem[i].firtdik;trcpy(u_opentable.openitem[j].name,name);u_opentable.openitem[j].ize=cur_dir->directitem[i].ize;u_opentable.cur_ize++;/某----------返回用户打开表表项的序号--------------------------某/return(j);}/某----------------------------------------------------------------------------------------------某//某----------------------------------------关闭文件----------------------------------------------某/intcloe(char某name){inti;for(i=0;i{if(!trcmp(u_opentable.openitem[i].name,name))break;}if(i>=MOFN)/某--文件没有打开-某/return(-1);/某-----------清空该文件的用户打开表项的内容---------------------某/trcpy(u_opentable.openitem[i].name,\u_opentable.openitem[i].fir tdik=-1;u_opentable.openitem[i].ize=0;u_opentable.cur_ize--;fd=-1;/某文件打开表的序号为-1某/return0;}/某----------------------------------------------------------------------------------------------某//某----------------------------------------写文件------------------------------------------------某/intwrite(intfd,char某buf,intlen){char某firt;intitem,i,j,k;intilen1,ilen2,modlen,temp;/某----------用$字符作为空格#字符作为换行符-----------------------某/charSpace=32;/某SPACE的ASCII码值某/charEndter='\\n';for(i=0;iif(buf[i]=='$')/某用$字符作为空格某/buf[i]=Space;eleif(buf[i]=='#')buf[i]=Endter;}/某----------读取用户打开表对应表项第一个盘块号-----------------------某/item=u_opentable.openitem[fd].firtdik;/某-------------找到当前目录所对应表项的序号-------------------------某/for(i=2;iif(cur_dir->directitem[i].firtdik==item)break;}temp=i;/某-存放当前目录项的下标-某//某------找到的item是该文件的最后一块磁盘块-------------------某/while(fat[item].item!=-1){item=fat[item].item;/某-查找该文件的下一盘块--某/}/某-----计算除该文件的最末地址-------某/firt=fdik+item某DISKSIZE+u_opentable.openitem[fd].ize%DISKSIZE;/某-----如果最后磁盘块剩余的大小大于要写入的文件的大小-------某/if(DISKSIZE-u_opentable.openitem[fd].ize%DISKSIZE>len){ trcpy(firt,buf);u_opentable.openitem[fd].ize=u_opentable.openitem[fd].ize+le n;cur_dir->directitem[temp].ize=cur_dir->directitem[temp].ize+len;}ele{for(i=0;i/某-----计算分配完最后一块磁盘的剩余空间(字节)还剩下多少字节未存储-------某/ilen1=len-(DISKSIZE-u_opentable.openitem[fd].ize%DISKSIZE);ilen2=ilen1/DISKSIZE;modl en=ilen1%DISKSIZE;if(modlen>0)ilen2=ilen2+1;/某--还需要多少块磁盘块-某//某调试时特别注意某/for(j=0;jfor(i=ROOT_DISK_NO+1;iif(fat[i].em_dik=='0')break;}if(i>=DISK_NUM)/某--如果磁盘块已经分配完了-某/return(-1);firt=fdik+i某DISKSIZE;/某--找到的那块空闲磁盘块的起始地址-某/if(j==ilen2-1)/某--如果是最后要分配的一块-某/{for(k=0;kele/某-如果不是要最后分配的一块--某/{for(k=0;kfat[item].item=i;/某--找到一块后将它的序号存放在上一块的指针中-某/fat[i].em_dik='1';/某--置找到的磁盘快的空闲标志位为已分配-某/fat[i].item=-1;/某--它的指针为-1(即没有下一块)-某/} /某--修改文件打开表用户的长度-某/u_opentable.openitem[fd].ize=u_opentable.openitem[fd].ize+le n;/某--修改目录项的文件长度-某/cur_dir->directitem[temp].ize=cur_dir->directitem[temp].ize+len;}return0;}/某----------------------------------------------------------------------------------------------某//某----------------------------------------读文件------------------------------------------------某/intread(intfd,char某buf){intlen=u_opentable.openitem[fd].ize;char某firt;inti,j,item;intilen1,modlen;item=u_opentable.openitem[fd].firtdik;if(len>u_opentable.openitem[fd].ize)/某--欲读出的文件长度比实际文件长度长-某/return(-1);ilen1=len/DISKSIZE;modlen=len%DISKSIZE;if(modlen!=0)ilen1=ilen1+1;/某--计算文件所占磁盘的块数-某/firt=fdik+item某DISKSIZE;/某--计算文件的起始位置-某/for(i=0;i{if(i==ilen1-1)/某--如果在最后一个磁盘块-某/{for(j=0;jele/某--不在最后一块磁盘块-某/{for(j=0;jitem=fat[item].item;/某-查找下一盘块-某/firt=fdik+item某DISKSIZE;}}return0;}/某----------------------------------------------------------------------------------------------某//某----------------------------------------删除文件----------------------------------------------某/intdel(char某name){inti,cur_item,item,temp;for(i=2;iif(!trcmp(cur_dir->directitem[i].name,name))break;}cur_item=i;/某--用来保存目录项的序号,供释放目录中-某/if(i>=MSD+2)/某--如果不在当前目录中-某/return(-1);if(cur_dir->directitem[cur_item].property!='0')/某--如果删除的(不)是目录-某/return(-3);for(i=0;iif(!trcmp(u_opentable.openitem[i].name,name))return(-2);}item=cur_dir->directitem[cur_item].firtdik;/某--该文件的起始盘块号-某/while(item!=-1)/某--释放空间,将FAT表对应项进行修改-某/{temp=fat[item].item;fat[item].item=-1;fat[item].em_dik='0';item=temp;}/某-----------------释放目录项-----------------------某/cur_dir->directitem[cur_item].ign=0;cur_dir->directitem[cur_item].firtdik=-1;trcpy(u_opentable.openitem[cur_item].name,\cur_dir->directitem[cur_item].ne某t=-1;cur_dir->directitem[cur_item].property='0';cur_dir->directitem[cur_item].ize=0;return0;}/某----------------------------------------------------------------------------------------------某//某---------------------------------------创建子目录---------------------------------------------某/intmkdir(char某name){inti,j;tructdirect某cur_mkdir;if(trchr(name,'\\\\'))/某如果目录名中有'\\'字符某/return(-4);if(!trcmp(name,\return(-6);if(!trcmp(name,\return(-6);if(trlen(name)>8)/某-如果目录名长度大于8位-某/return(-1);for(i=2;iif(cur_dir->directitem[i].firtdik==-1)break;}if(i>=MSD+2)/某-目录/文件已满-某/return(-2);for(j=2;jif(!trcmp(cur_dir->directitem[j].name,name))break;}if(jfor(j=ROOT_DISK_NO+1;jif(fat[j].em_dik=='0')break;}if(j>=DISK_NUM)return(-5);fat[j].em_dik='1';/某-将该空闲块设置为已分配-某//某-------------填写目录项----------某/trcpy(cur_dir->directitem[i].name,name);cur_dir->directitem[i].firtdik=j;cur_dir->directitem[i].ize=ROOT_DISK_SIZE;cur_dir->directitem[i].ne某t=j;/某-指向子目录(其实就是其本身)的起始盘块号-某/cur_dir->directitem[i].property='1';/某-ign=1为根标志,这里可以省略-某//某-所创目录在虚拟磁盘上的地址(内存物理地址)-某/cur_mkdir=(tructdirect某)(fdik+cur_dir->directitem[i].firtdik某DISKSIZE);/某-初始化目录-某//某-指向当前目录的目录项-某/cur_mkdir->directitem[0].ign=0;cur_mkdir->directitem[0].firtdik=cur_dir->directitem[i].firtdik;trcpy(cur_mkdir->directitem[0].name,\ cur_mkdir->directitem[0].ne某t=cur_mkdir->directitem[0].firtdik;cur_mkdir->directitem[0].property='1';cur_mkdir->directitem[0].ize=ROOT_DISK_SIZE;/某-指向上一级目录的目录项-某/cur_mkdir->directitem[1].ign=cur_dir->directitem[0].ign;/某-指向上一级目录的目录项-某/cur_mkdir->directitem[1].firtdik=cur_dir->directitem[0].firtdik;trcpy(cur_mkdir->directitem[1].name,\ cur_mkdir->directitem[1].ne某t=cur_mkdir->directitem[1].firtdik;cur_mkdir->directitem[1].property='1';cur_mkdir->directitem[1].ize=ROOT_DISK_SIZE;for(i=2;icur_mkdir->directitem[i].ign=0;cur_mkdir->directitem[i].firtdik=-1;trcpy(cur_mkdir->directitem[i].name,\cur_mkdir->directitem[i].ne某t=-1;cur_mkdir->directitem[i].property='0';cur_mkdir->directitem[i].ize=0;} return0;}/某----------------------------------------------------------------------------------------------某//某---------------------------------------删除子目录---------------------------------------------某/intrmdir(char某name){inti,j,item;tructdirect某temp_dir;/某-检查当前目录项中有无该目录-某/for(i=2;iif(!trcmp(cur_dir->directitem[i].name,name))break;}if(cur_dir->directitem[i].property!='1')/某-删除的不是目录-某/return(-3);if(i>=MSD+2)/某-没有这个文件或目录-某/return(-1);/某-判断要删除的目录有无子目录-某//某-要删除的目录起始地址-某/temp_dir=(tructdirect某)(fdik+cur_dir->directitem[i].ne某t 某DISKSIZE);for(j=2;jif(temp_dir->directitem[j].ne某t!=-1)break;}if(jreturn(-2);/某-有关联则报错,也可以采取级联删除,像Window-某//某------------找到起始盘块号,并将其释放----------------某/item=cur_dir->directitem[i].firtdik;fat[item].em_dik='0';/某-修改目录项-某/cur_dir->directitem[i].ign=0;cur_dir->directitem[i].firtdik=-1;trcpy(cur_dir->directitem[i].name,\cur_dir->directitem[i].ne某t=-1;cur_dir->directitem[i].property='0';cur_dir->directitem[i].ize=0;return0;}/某----------------------------------------------------------------------------------------------某//某-------------------------------显示当前目录的子目录-------------------------------------------某/voiddir(){inti;for(i=0;iif(cur_dir->directitem[i].firtdik!=-1)/某-如果存在子目录-某/{/某-其本身和父目录也算-某/printf(\if(cur_dir->directitem[i].property=='0')/某-文件-某/printf(\ele/某-目录-某/printf(\}}}/某----------------------------------------------------------------------------------------------某//某---------------------------------------更改当前目录-------------------------------------------某/intcd(char某name){inti,j,item;char某tr,某tr1;char某temp,某point,某point1;tructdirect某temp_dir;temp_dir=cur_dir;/某-先用临时目录代替当前目录-某/tr=name;/某-tr用来记录下次查找的起始地址-某/if(!trcmp(\如果输入\回根目录某/{cur_dir=root;trcpy(bufferdir,\return0;}j=0;for(i=0;iif(name[i]=='\\\\'){j++;if(j>=2){return-3;}}elej=0;}if(name[0]=='\\\\')/某如果最后一个是\去掉这个\{temp_dir=root;trcpy(bufferdir,\tr++;}if(tr[trlen(tr)-1]=='\\\\'){tr[trlen(tr)-1]='\\0';}tr1=trchr(tr,'\\\\');/某-找到'\\'字符的位置-某/temp=(char某)malloc(DIR_LENGTH某izeof(char));/某-为子目录的名字分配空间-某/while(tr1!=NULL)/某-找到-某/{for(i=0;itemp[i]=tr[i];}temp[i]='\\0';for(j=2;jif(!trcmp(temp_dir->directitem[j].name,temp))break;}if(j>=MSD+2)/某-不在当前目录-某/return(-1);item=temp_dir->directitem[j].firtdik;temp_dir=(tructdirect某)(fdik+item某DISKSIZE);/某-计算当前目录物理位置-某/tr=tr1+1;tr1=trchr(tr,'\\\\');//free(temp);}tr1=tr1+trlen(tr);for(i=0;ifor(j=0;jif(!trcmp(temp_dir->directitem[j].name,temp))break;}free(temp);/某释放申请的临时空间某/if(temp_dir->directitem[j].property!='1')/某-打开的不是目录-某/return(-2);if(j>=MSD+2)/某-不在当前目录-某/return(-1);item=temp_dir->directitem[j].firtdik;/某-当前目录在磁盘中位置-某/temp_dir=(tructdirect某)(fdik+item某DISKSIZE);if(!trcmp(\{if(cur_dir->directitem[j-1].ign!=1)/某-如果子目录不是根目录-某/{point=trchr(bufferdir,'\\\\');while(point!=NULL){point1=point+1;/某-减去'\\'所占的空间,记录下次查找的起始地址-某/point=trchr(point1,'\\\\');}某(point1-1)='\\0';/某-将上一级目录删除-某/}ele{}}eleif(!trcmp(\{bufferdir=bufferdir;/某-如果是当前目录则不变-某/}ele{if(name[0]!='\\\\')bufferdir=trcat(bufferdir,\修改当前目录-某/bufferdir=trcat(bufferdir,name);}cur_dir=temp_dir;/某-将当前目录确定下来-某/return0;}/某----------------------------------------------------------------------------------------------某//某---------------------------------------显示当前路径-------------------------------------------某/voidhow(){printf(\}/某----------------------------------------------------------------------------------------------某//某--------------------------------------输出提示信息--------------------------------------------某/voidprint(){printf(\退出文件系统halt\\n\printf(\创建文件create文件名\\n\printf(\删除文件del文件名\\n\printf(\打开文件open文件名\\n\printf(\关闭文件cloe文件名\\n\printf(\写文件write\\n\printf(\读文件read\\n\\n\printf(\创建子目录mkdir目录名\\n\printf(\删除子目录rmdir目录名\\n\printf(\显示当前目录的子目录dir\\n\printf(\更改当前目录cd目录名\\n\}/某----------------------------------------------------------------------------------------------某//某------------------------------------------主函数----------------------------------------------某/intmain(){FILE某fp;charch;chara[100];charcode[11][10];charname[10];inti,flag,r_ize;char某contect;contect=(char某)malloc(MA某_WRITE某izeof(char));if((fp=fopen(\如果还没有进行格式化,则要格式化某/{printf(\canf(\if(ch=='y'){initfile();printf(\}ele{//return;}}enter();print();how();/某将命令全部保存在CODE数组中某/trcpy(code[0],\trcpy(code[1],\trcpy(code[2],\trcpy(code[3],\trc py(code[4],\trcpy(code[5],\trcpy(code[6],\trcpy(code[7],\trcpy(c ode[8],\trcpy(code[9],\trcpy(code[10],\while(1){canf(\for(i=0;i<11;i++){if(!trcmp(code[i],a))break;}witch(i){cae0://某--退出文件系统--//free(contect);halt();//return;cae1://某--创建文件--//canf(\flag=create(name);if(flag==-1){ printf(\}eleif(flag==-2){printf(\}eleif(flag==-3){printf(\}eleif(flag==-4){printf(\}eleif(flag==-5){printf(\}ele{printf(\}how();break;cae2://--打开文件--//canf(\fd=open(name);if(fd==-1){ printf(\}eleif(fd==-2){printf(\}eleif(fd==-3){printf(\}eleif(fd==-4){printf(\}ele{printf(\}how();break;cae3://--关闭文件--//canf(\flag=cloe(name);if(flag==-1){ printf(\}ele{printf(\}how();break;cae4:/某--写文件--某/if(fd==-1){printf(\}ele{printf(\canf(\flag=write(fd,contect,trlen(contect));if(flag==0){ printf(\}ele{printf(\}}how();break;cae5:/某--读文件--某/if(fd==-1){printf(\}ele{flag=read(fd,contect);if(flag==-1){printf(\}ele{//printf(\for(i=0;iprintf(\}printf(\}}how();break;cae6://某--删除文件--canf(\flag=del(name);if(flag==-1){ printf(\}eleif(flag==-2){printf(\}eleif(flag==-3){printf(\}ele{printf(\}how();break;cae7://某--创建子目录--/canf(\flag=mkdir(name);if(flag==-1){ printf(\}eleif(flag==-2){printf(\}eleif(flag==-3){printf(\}eleif(flag==-4){printf(\}eleif(flag==-5){printf(\}eleif(flag==-6){printf(\}eleif(flag==0){printf(\}how();break;cae8://某--删除子目录--/canf(\flag=rmdir(name);if(flag==-1){ printf(\}eleif(flag==-2){printf(\}eleif(flag==-3){printf(\}eleif(flag==0){printf(\}how();break;cae9://某--显示当前子目录--/dir();how();break;cae10:/某--更改当前目录--某/canf(\flag=cd(name);if(flag==-1) {printf(\}eleif(flag==-2){printf(\}eleif(flag==-3){printf(\}how();break;default:printf(\how();}}}。
操作系统 实验4:文件管理实验报告
一、实验题目:文件管理实验--Linux下的文件管理二、实验目的和要求:实验目的:(1)加深对文件、目录、文件系统等概念的理解。
(2)掌握 Linux 文件系统的目录结构。
(3)掌握有关 Linux 文件系统操作的常用命令。
(4)了解有关文件安全性方面的知识。
实验要求:(1)正确使用文件管理命令,能熟练地对文件进行浏览、拷贝、移动和删除。
(2)能熟练地确定和更改工作目录,查看内容和文件属性,创建和删除目录。
(3)正确地理解文件的权限,并能进行相应更改。
(4)理解文件的类型及其表示形式。
(5)理解文件名的表示形式,在模式匹配中能正确使用通配符。
三、实验内容:(1)使用pwd,cd,ls等命令浏览文件系统。
(2)使用cat,cp,mv,head,tail,rm等命令查看你的文件。
(3)使用ln命令进行文件的硬连接和符号连接。
软中断通信(4)使用find,grep命令进行文件查找和模式匹配。
(5)使用chmod命令修改文件的权限。
四、实验步骤:(说明:对本实验涉及的教材中的相关内容进行归纳总结,只需简要说明即可。
)1、用root账号登录到终端,使用pwd命令查看当前目录2、用cd命令将当前目录切换到“/”目录下3、使用ls明令查看Linux的目录结构,了解各目录存放与系统相关的文件14、使用 cat、more、head、tail等命令显示 /etc/inittab文件内容5、使用grep 命令在/etc/inittab 文件中查询“initdefault”字符串26、使用find 命令查找 /目录下所有以main 开头的文件7、使用 cp 命令将/etc目录下的inittab文件拷贝到/root目录下8、使用 sort 和uniq 命令对 /root目录下的inittab文件排序后输出其结果39、统计inittab文件的字节数、行数、字数10、用mkdir命令在/root目录下创建一个test目录11、用cp命令将/etc目录及其下所有内容复制到test目录下12、使用cd和ls查看/root/test/etc 下的内容413、将test目录改名为test214、删除test2五、实验总结:通过本次实验,让我懂得了怎样创建文件以及文件管理命令的使用,对Linux的掌握和了解进一步加深。
操作系统实验四 文件系统实验
return
scanf("%s",s); strcpy(t->fileName,s); printf("\n 请输入该文件基本信息:"); scanf("%s",s); strcpy(t->file,s); t->brother=t->child=NULL; if(p->child==NULL) {
goto label; } p=p->next; } printf("文件不存在!\n"); goto label; } else if(i==8) { show(f); goto label; } else { goto label; } } void Select() { char username[20]; int i; printf("请输入用户名:\n"); scanf("%s",username); for(i=0; i<userNum; i++) { if(!strcmp(mdf[i].userName,username)) { fp= mdf[i].p; if(fp!=NULL) {
printf("该用户已创建文件:\n"); while(fp!=NULL) {
fp=fp->next; printf("%s\n",fp->fileName); } } else { printf("该用户尚未创建任何文件!\n"); } fp= mdf[i].p; Operation(fp); }
#include <stdio.h> #include <stdlib.h> #include <string.h> #define getpch(type) (type*)malloc(sizeof(type)) int userNum=0;
实验4文件系统实验
b.移动多个文件
c.移动目录
d.重命名目录
2)借助google工具查找资料,学习Linux文件系统中关于文件硬链接和软链接的概念和相关操作命令;
1相关概念:
【硬连接】
硬连接指通过索引节点来进行连接。在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号(Inode Index)。在Linux中,多个文件名指向同一索引节点是存在的。一般这种连接就是硬连接。硬连接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬连接到重要文件,以防止“误删”的功能。其原因如上所述,因为对应该目录的索引节点有一个以上的连接。只删除一个连接并不影响索引节点本身和其它的连接,只有当最后一个连接被删除后,文件的数据块及目录的连接才会被释放。也就是说,文件真正删除的条件是与之相关的所有硬连接文件均被删除。
指导教师签字:
年月日
备注:
注:1、报告内的项目或内容设置,可根据实际情况加以调整和补充。
2、教师批改学生实验报告时间应在学生提交实验报告时间后10日内。
- r若源文件是一目录文件,此时cp将递归复制该目录下所有的子目录和文件。当然,目标文件必须为一个目录名。
- l不作拷贝,只是链接文件。
-s复制成符号连结文件(symbolic link),亦即『快捷方式』档案;
-u若destination比source旧才更新destination。
a.文件到文件复制:将文档a复制成b(相当于备份并改名)。
d设定时间与日期,可以使用各种不同的格式。
t设定档案的时间记录,格式与date指令相同。
--no-create不会建立新档案。
--help列出指令格式。
实验4(文件系统)
实验4 文件系统一、目的与要求1. 目的文件系统是操作系统的一个重要组成部分,也是与用户关系极为密切的部分。
学生应独立的用高级语言编写和调试一个简单的文件系统,模拟文件管理的工作过程,从而对各种文件操作命令的实质内容和执行过程有比较深入的了解,掌握它们的实施方法,加深对教材中有关内容的理解。
2. 要求(1)设计一个n个用户的文件系统,每个用户最多可保存m个文件。
(2)限制用户在一次运行中只能打开一个文件。
(3)系统应能检查输入命令的正确性,出错时要能显示出错原因。
(4)对文件必须设置保护措施,如只能执行,允许读,允许写等。
在每次打开文件时,根据本次打开的要求,再次设置保护级别,即可有二级保护。
(5)对文件的操作至少应有下面几条命令:create 建立文件delete 删除文件open 打开文件close 关闭文件read 读文件write 写文件(6)本次实验的上机时间为2~4学时。
二、实验内容1. 题目(1)本次实验设计一个共有10个用户的文件系统,每个用户最多可保存10个文件,一次运行过程中用户可同时打开5个文件。
(2)程序采用二级文件目录,即设置了主文件目录(MFD)和用户文件目录(UFD)。
前者应包含文件主(即用户)及他们的目录区指针;后者应给出每个文件主占有的文件目录,即文件名、保护码、文件长度以及它们存放的位置等。
另外为打开文件设置了运行文件目录(AFD),在文件打开时应填入打开文件号,本次打开保护码和读写指针等。
(3)为了便于实现,对文件的读写作了简化,在执行读写命令时,只修改读写指针,并不进行实际文件的读写操作。
2. 算法与框图(1)因系统小,文件目录的检索使用了简单的线性搜索,而没有采用Hash等有效算法。
(2)文件保护简单使用了三位保护码,对应于允许读,允许写和允许执行,如下所示:1 1 1允许读允许写允许执行如对应位为0,则不允许。
(3)程序中使用的主要数据结构如下:①主文件目录(MFD)和用户文件目录(UFD)MFD UFD②(4)程序框图5-1所示:三、参考书目[1] 郭浩志主编,计算机软件实践教程,西北电讯工程学院出版社,1995年(第二版)[2] 庞丽萍,李胜利编,操作系统原理,华中科技大学出版社,2000年(第三版)[3] 汤子瀛,杨成武编著,计算机操作系统,西北电讯工业大学出版社(第二版)。
Linux实验4-Linux文件系统-目录和文件管理
实验报告课程名称: Linux操作系统实验名称:实验4、Linux文件系统-目录和文件管理学生姓名:班级学号学院(系):指导教师:实验时间:年月日实验成绩:实验四、Linux文件系统-目录和文件管理一、实验要求(1)掌握目录和文件管理的操作命令;(2)掌握文件权限的修改方法。
(3)掌握文件链接的方法。
二、实验内容和实验步骤【操作要求1】查看Linux系统常见的目录。
【操作步骤】输入命令:ls,查看Linux系统常见的目录,截图如下:【操作要求2】显示当前目录下文件类型。
【操作步骤】输入命令:ls –l|more,截图如下:说明:●“-”:表示普通文件●“d”:表示目录文件●“c”:表示字符设备文件●“b”:表示块设备文件●“l”:表示符号链接文件【操作要求3】查看当前目录下所有文件类型【操作步骤】输入命令:file *,截图如下:【操作要求4】先创建两个新目录dir1和dir2,然后将dir2目录移到dir1目录中,最后删除dir2目录。
【操作步骤】(1)以普通用户user登陆字符界面,输入命令:pwd,当前目录为用户的主目录:/home/user。
(2)输入命令:ls –l,查看当前目录中的所有文件。
(3)创建两个目录,输入命令:mkdir dir{1,2}。
(4)输入命令:ls –l,确认两个目录创建成功。
以上4个步骤截图如下:(5)输入命令:mv dir2 dir1,将dir2目录移动到dir1目录。
(6)输入命令:cd dir1,切换dir1目录,再输入:ls命令,查看到dir2目录。
截图如下:(7)删除dir2目录,输入命令:rm –rf dir2。
【操作要求5】查找profile文件。
【操作步骤】(1)切换用户为超级用户,输入命令:su -,并输入密码。
(2)输入命令:find /etc -name profile, 截图如下:(3) 使用exit命令,退出超级用户身份。
【操作要求6】将/etc/profile文件中所有包含“HOSTNAME”的行存入f4文件,并修改f4文件的权限,让所有用户都可以读写。
实验4:文件系统
操作系统实验报告实验题目:文件系统专业计算机科学与技术学生姓名班级学号指导教师肖莹指导单位计算机学院日期一、实验目的1. 学习Linux系统下对文件进行操作的各种命令和图形化界面的使用方法。
二、实验指导1.文件系统常用命令操作1)ls 命令用来查看用户有执行权限的任意目录中的文件列表,该命令有许多的选项。
例如:$ ls -liah *22684 -rw-r--r-- 1 bluher users 952 Dec 28 18:43 .profile19942 -rw-r--r-- 1 scalish users 30 Jan 3 20:00 test2.out925 -rwxr-xr-x 1 scalish users 378 Sep 2 2002 test.sh上面的列表显示8 列:第1 列指示文件的inode,因为我们使用了-i 选项。
剩下的列通过-l 选项来进行正常显示。
第2 列显示文件类型和文件访问权限。
第3 列显示链接数,包括目录。
第4 和第 5 列显示文件的所有者和组所有者。
这里,所有者'bluher' 属于组'users'。
第 6 列显示文件大小(单位为所显示的单位,而不是默认的字节数,因为我们使用了-h 选项。
第7 列显示日期(它看起来像是三列),包括月、日和年,以及当天的时间。
第8 列显示文件名。
在选项列表中使用-a 将使列表中包含隐藏文件(如.profile)的列表。
(隐藏文件以.开始命名)(要求:1、任意选择一个文件夹,显示其中的所有文件的详细信息;2、自己在该文件夹内创建一个隐藏文件,调用扩展的ls命令,不显示该隐藏文件,但需要显示其他非隐藏文件的详细信息。
随后,调用带参数的ls命令,显示该隐藏文件)2)带参数的rm命令$ rm -ir Testrm:descend into directory `Test'? y可以用mkdir 来创建目录,用rmdir 来删除目录。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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 { return -1; } }
HashFile.c
#include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #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; hfh.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))*total_rec_num); rtn=write(fd,buf,(reclen+sizeof(struct CFTag))*total_rec_num); free(buf);
•
参考代码
• • • • HashFile.h HashFile.c 测试程序jtRecord.h 测试程序jtRecord.c
HashFile.h
#include <unistd.h> #define COLLISIONFACTOR 0.5 //Hash函数冲突 因子 struct HashFien; //记录长度 int total_rec_num; //总记录数 int current_rec_num; //当前记录数 };
•
实验设计
• 由于在Linux系统核心之外模拟实现hash文件, 有关hash文件的说明信息不能保存在inode中, 而只能记录在文件的头部。这些信息包括hash文 件标志、记录大小、文件长度、记录数量等。 可以根据hash文件核心算法设计内部函数,包括 记录的保存、查找、删除等,在此基础上实现 读、写等常规操作。
} close(fd); return rtn; } else { close(fd); return -1; } } int hashfile_open(const char *filename,int flags, mode_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; }
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); int hashfile_open(const char *filename,int flags, mode_t mode); 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_saverec(int fd,int keyoffset,int keylen,void *buf); int hash(int keyoffset,int keylen,void *buf,int recnum); int checkHashFileFull(int fd); int readHashFileHeader(int fd,struct HashFileHeader *hfh )
实验四 文件系统——Hash结构 文件
• • • • • • • 实验目的 实验内容 实验准备 实验设计 参考代码 实验结果 思考题
实验目的
• 理解Linux文件系统的内部技术,掌握 Linux与文件有关的系统调用命令,并在此 基础上建立面向随机检索的hash结构文件。 • Linux系统保持UNIX文件系统的风格,提 供流式文件界面,这种结构具有简洁灵活 的特点,但并不直接支持记录式文件和关 键字检索。本实验是在Linux文件系统基础 上,设计一组库函数,以提供对随机检索 的支持。
实验内容
• 参考教材中hash文件构造算法,设计一组 hash文件函数,包括hash文件创建、打开、 关闭、读、写等。 • 编写一个测试程序,通过记录保存、查找、 删除等操作,检查上述hash文件是否实现 相关功能。
实验准备
• 教程Hash文件核心算法,包括记录保存、记 录查找、记录删除等。 教程Linux系统有关文件的系统调用命令: creat,open,close,read,write,lseek。
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) return -1; 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(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,%s}\n",((struct jtRecord*)p)->key,((struct jtRecord*)p)->other); char *p1,*p2; p1=(char*)buf+keyoffset; p2=p+keyoffset; int j=0;
while((*p1==*p2)&&(j<keylen)) { p1++; p2++; j++; } if(j==keylen) { free(p); p=NULL; return (offset); //找到,返回偏移值 } else { if(addr==hash(keyoffset,keylen,p,hfh.total_rec_num)) { count--; //hash值相等而key值不等 if(count==0) { free(p); p=NULL; return -1; //不存在 } }
else return -1;
} int hashfile_close(int fd) { return close(fd); } int hashfile_read(int fd,int keyoffset,int keylen,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; } }