操作系统实习报告--文件管理模拟

时间:2024.4.1

操作系统小学期

               ----文件管理模拟

       学院信息科学与技术 

       专业计算机科学与技术

       年级               

       班级                

       姓名                 

       学号              

       日期20119月   

一.问题描述

   文件管理是操作系统的五大职能之一,主要涉及文件的逻辑组织和物理组织,目录的结构和管理。主要的磁盘调度算法有:1.先来先服务算法(FCFS); 2.最短寻道时间优先算法(SSTF); 3.扫描算法(SCAN); 4.循环扫描算法(CSCAN)等。

用程序模拟磁盘的调度过程,并计算各磁盘调度算法包括先来先服务算法、最短寻道时间优先算法、扫描算法和循环扫描算法的平均寻道长度。

二.问题分析

在多道程序设计的计算机系统中,各个进程可能会不断提出不同的对磁盘进行读/写操作的请求。由于有时候这些进程的发送请求的速度比磁盘响应的还要快,因此我们有必要为每个磁盘设备建立一个等待队列。

先来先服务(FCFS :afirst-come-first-served)的策略,即先来的请求先被响应。FCFS策略看起来似乎是相当"公平"的,但是当请求的频率过高的时候FCFS策略的响应时间就会大大延长。FCFS策略为我们建立起一个随机访问机制的模型,但是假如用这个策略反复响应从里到外的请求,那么将会消耗大量的时间。为了尽量降低寻道时间,看来我们需要对等待着的请求进行适当的排序,而不是简单的使用FCFS策略。这个过程就叫做磁盘调度管理。有时候fcfs也被看作是最简单的磁盘调度算法。
     最短时间优先算法(SSTF)选择这样的进程。要求访问的磁道,与当前磁头所在的磁道距离最近,以使每次的寻道时间最短。
     扫描(SCAN)调度算法:该算法不仅考虑到欲访问 的磁道与当前磁道间的距离,更优先考虑的是磁头当前的移动方向。例如,当磁头正在自里向外移动时,SCAN算法所考虑的下一个访问对象,应是其欲访问的磁道,既在当前磁道之外,又是距离最近的。这样自里向外的访问,直至再无更外的磁道需要访问时,才将磁道换向自外向里移动。这时,同样也是每次选择这样的进程来调度,也就是要访问的当前位置内距离最近者,这样,磁头又逐步地从外向里移动,直至再无更里面的磁道要访问,从而避免了出现“饥饿”现像。

循环扫描(CSCAN)算法:当磁头刚从里向外移动而越过了某一磁道时,恰好又有一进程请求访问此磁道,这时,该里程就必须等待,为了减少这种延迟,CSCAN算法规定磁头单向移动,本实验已完全能演示循环扫描的全过程。

三.数据模型描述

int Hand = 10;  //初始的磁道数

 int limit = 10; //寻找的范围

int Jage=0;

float Aver = 0;

 int NAll = 0;

int[] Dis = new int[10];//存放寻道顺序

 int[,] Best=new int[50,2]; //Best[][1]存放移动磁道数,Best[][0]存放算法的序号

四.算法描述

(1)先来先服务算法(FCFS)

public void FCFS(int Han,int []DiscL)

{  int []RLine = new int[10];

   int i,k,All,Temp;//Temp是算移动的磁道距离的临时量

   All=0;  //统计全部的磁道数变量

   k=9;  //限定10个的磁道数

   CopyL(DiscL,RLine,9);  //复制磁道号到临时数组RLine

   All=Han-RLine[0];

   for(i=0;i<=9;i++)

   {

      Temp=RLine[0]-RLine[1];

      if(Temp<0)

      Temp=(-Temp);//移动磁道数为负数时算出相反数作为移动磁道数

      result.Text += RLine[0]+"  ";

      All=Temp+All; DelInq(RLine,0,k); k--;

    }

    Best[Jage,1]=All;//Best[][1]存放移动磁道数

    Best[Jage,0]=1; //Best[][0]存放算法的序号为:1

    Jage++; Aver=((float) All)/10;//求平均寻道次数

    label7.Text = All.ToString();label9.Text = Aver.ToString();

 }

流程图如下:

 (2)最短时间优先算法(SSTF)

public  void SSTF(int Han,int []DiscL)

{

    int i,j,k,h,All;

    int Temp;  //Temp是计算移动的磁道距离的临时变量

   int[] RLine=new int[10]; //将随机生成的磁道数数组Discl[]复制给数组RLine[]

   int Min;

   h = 0;

   All=0;  //统计全部的磁道数变量

    k=9;  //限定10个的磁道数

     CopyL(DiscL,RLine,9);  //复制磁道号到临时数组RLine

      for(i=0;i<=9;i++)

     {

             Min=64000;

          for(j=0;j<=k;j++) //内循环寻找与当前磁道号最短寻道的时间的磁道号

          {

              if(RLine[j]>Han)//如果第一个随机生成的磁道号大于当前的磁道号执行下一句

                  Temp=RLine[j]-Han;  //求出临时À的移动距离

              else

                  Temp=Han-RLine[j];  //求出临时的移动距离

              if(Temp<Min)  //如果每求出一次的移动距离小于Min执行下一句

              {

                  Min=Temp;  //Temp临时值赋予Min

                  h=j;  //把最近当前磁道号的数组下标赋予h

              }

           }

           All=All+Min;  //统计一共移动的距离

           result.Text += RLine[h] + "  ";

           Han=RLine[h]; 

           DelInq(RLine,h,k);  //每个磁道数向前移动一位

           k--;

      }

     Best[Jage,1]=All;//Best[][1]存放移动磁道数

     Best[Jage,0]=2;//Best[][0]存放算法的序?为a:2

     Jage++;//排序序号加

     Aver=((float)All)/10;//求平均寻道次数

     label7.Text = All.ToString();

     label9.Text = Aver.ToString();

 }

流程图如下:

(3)扫描算法(SCAN)

public int SCAN(int Han,int []DiscL,int x,int y)

{

    int j,n,k,h=0,m,All;int t=0; int Temp; int Min;

   int []RLine=new int[10]; //将随机生成的磁道数数Discl[]复制给数组RLine[]

   int Order; Order=1;k=y;

  m=2;  //控制while语句的执行          

 All=0;  //统计全部的磁道数变量

 CopyL(DiscL,RLine,9);  //复制磁道号到临时数组RLine

   Min=64000;

  for(j=x;j<=y;j++)  //寻找与当前磁道号最短寻道的时间的磁道号

  {

     if(RLine[j]>Han)  //如果第一个磁道号大于当前的磁道号执行下一句

        Temp=RLine[j]-Han;  //求出临时的移动距离

     else

        Temp=Han-RLine[j];  //求出临时的移动距离

     if(Temp<Min)

    {

        Min=Temp;  //Temp临时值赋予Min

        h=j;   //把最近当前磁道号的数组下标赋予

    }

  }

  All=All+Min; 

   result.Text += RLine[h] + "  ";

  if(RLine[h]>=Han)

{  //判断磁道的移动方向,即是由里向外还是由外向里

     Order=0; t=1;

  }

 Han=RLine[h];

 DelInq(RLine,h,k);  //每个磁道数向前移动一位

  k--;

 while(m>0) 

 {

    if(Order==1)  //order是判断磁盘扫描的方向标签,order是1的话磁道向内移动

    {

       for(j=x;j<=y;j++) 

      {

         h=-1;

         Min=64000;

         for(n=x;n<=k;n++)  //判断离当前磁道最近的磁道号?

         {

             if(RLine[n]<=Han)

            {

               Temp=Han-RLine[n];

                if(Temp<Min)

                {

                   Min=Temp;  //Temp临时值赋予Min

                    h=n;  //把最近当前磁道号的数组下标赋予

                }

             }

         }

         if(h!=-1)

         {

                 All=All+Min;  //叠加移动距离

                 result.Text += RLine[h] + "  ";

                 Han=RLine[h]; //最近磁道号作为当前磁道

                DelInq(RLine,h,k);

                k--;

          }

       }

       Order=0;  //当完成向内的移动order赋予0执行Delse语句,使磁道向外移动

         m--;  //向内完成一次,m减一次,保证while循-环执行两次

    }

    else  //order是0的话,磁道向外移动

    {

        for(j=x;j<=y;j++)

        {  h=-1;Min=64000;

           for(n=x;n<=k;n++)  //判断离当前磁道最近的磁道号?

           {

              if(RLine[n]>=Han)

              {

                 Temp=RLine[n]-Han;

                 if(Temp<Min)

                {  

                     Min=Temp;   //Temp临时值赋予Min

                     h=n;  //把最近当前磁道号的数组下标赋予

                  }

                }

             }

             if(h!=-1)

             {

                 All=All+Min;  //叠加移动距离

                result.Text += RLine[h] + "  ";

                Han=RLine[h];  //最近的磁道号作为当前磁道

                DelInq(RLine,h,k); k--;

             }

           }

           Order=1; //当完成向内的移动order赋予0执行Delse语句使磁道向外移

             m--;   //向内完成一次减一次,保证while循-环执行两次

         }

       }

        NAll=NAll+All;

        if((y-x)>5)

         {

             Best[Jage,1]=All;//Best[][1]存放移动磁道数

             Best[Jage,0]=3;//Best[][0]存放算法的序号为:3

             Jage++;//排序序号加1

             Aver=((float)All)/10;//求平均寻道次数

             label7.Text = All.ToString();

            label9.Text = Aver.ToString();

          }

          return(Han);

}

流程图如下:

(4)循环扫描算法(CSCAN)

    public void CSCAN(int Han,int []DiscL)

    {

        int j,h,n,Temp,m,k,All,Last,i;

int []RLine=new int[10]; //将磁道数数组Discl[]复制给数组RLine[]

        int Min;int tmp=0;m=2;k=9;

       All=0;   //统计全部的磁道数变量

        Last=Han;

        CopyL(DiscL,RLine,9);  //复制磁道号到临时数组RLine

          while(k>=0)

       {

 for(j=0;j<=9;j++)  //从当前磁道号开始由内向外搜索离当前磁道最近¨磁道号

            {  h=-1;

               Min=64000;

               for(n=0;n<=k;n++)

              {

                  if(RLine[n]>=Han)

                  {

                      Temp=RLine[n]-Han;

                          if(Temp<Min)

                       {

                          Min=Temp; h=n;

                       }

                    }

                 }

                 if(h!=-1)

                {      All=All+Min;  //统计一共移动的距离

                      result.Text += RLine[h] + "  ";

                     Han=RLine[h];

                     Last=RLine[h];

                     DelInq(RLine,h,k);

                     k--;

                  }

              }

               if(k>=0)

              {  tmp=RLine[0];

                 for(i=0;i<k;i++)//算出剩下磁道号的最小值

                 {   if(tmp>RLine[i]) tmp=RLine[i]; }

                Han=tmp;//把最小的磁道号赋给Han

                Temp=Last-tmp;//求出最大磁道号和最小磁道号的距离差

                All=All+Temp;

             }

          }//end whlie

          Best[Jage,1]=All;//Best[][1]存放移动磁道数

          Best[Jage,0]=4;//Best[][0]存放算法的序号为:4

          Jage++;//排序序号加1

          Aver=((float)All)/10;//求平均寻道次数

          label7.Text = All.ToString();

         label9.Text = Aver.ToString();

       }

流程图如下:

五.实习心得

此次设计基本完成了所规定的功能,但由于这次设计的时间比较仓促,其中不免会有些纰漏,比如在程序的实现上还不够严谨,出错处理不够完善等多方面问题,这些都有进一步改善。
由于平时上课不是很认真许多概念没有理解清楚,导致在做设计时有点无从下手的感觉,只好边实验边看书直到弄懂概念后才开始做设计导致时间有点紧张,最终在同学和老师的指导下我完成了设计,此设计基本能够实现规定的要求但是还是不够完善,很多东西做的不够好,程序不够完善和严谨。此次课程设计中我学到了很多东西,无论在理论上还是实践中,都得到不少的提高,这对于我以后的工作和学习都有一种巨大的帮助。


第二篇:操作系统实习报告(磁盘文件操作)


大学

操作系统课程综合实践

题目: 磁盘文件操作

班级:

姓名:

学号:

指导教师:

20xx年 12 月 23日

磁盘文件操作

摘要:

为了正确地实现文件的存取,文件系统设计了一组与存取文件有关的功能模块,用户可以用“访问指令”调用这些功能模块,以实现文件的存取要求。我们把文件系统设计的这一组功能模块称为“文件操作“,实验就是要模拟实现一些文件操作。文件操作不是独立的,它和文件系统的其他部分密切相关,若要实现文件操作就离不开文件的目录结构、文件的组织结构和磁盘空间的管理。因此,这个实习虽然是文件操作的模拟实现,但还是必须模拟一部分文件的组织结构、目录结构和磁盘空间管理的实现。

关键字:磁盘、文件、目录、分配表。

一、实验内容:

设计一个简单的文件系统,用文件模拟磁盘,用数组模拟缓冲区,要求实现; 1.

2.

3.

4. 支持多级目录结构,支持文件的绝对路径; 文件的逻辑结构采用流式结构,物理结构采用链接结构中的显示链接方式; 采用文件分配表; 实现的命令包括建立目录、列目录、删除空目录、建立文件、删除文件、

显示文件内容、打开文件、读文件、写文件(追加方式)、关闭文件、改变文件属性。

最后编写主函数对所做工作进行测试。

二、实验目的:

1、

2、

3、

4、 文件的操作。 文件的逻辑结构和物理结构 磁盘空间的管理 磁盘目录结构

三、实验环境:

Windows XP、VC++

四、程序运行结果(详图):

程序运行的主界面:用户运行命令7-建立目录

操作系统实习报告磁盘文件操作

用户运行命令1-建立文件:

操作系统实习报告磁盘文件操作

显示目录内容:

操作系统实习报告磁盘文件操作

打开文件:

操作系统实习报告磁盘文件操作

写文件:

操作系统实习报告磁盘文件操作

关闭文件:

操作系统实习报告磁盘文件操作

再次显示目录内容:

操作系统实习报告磁盘文件操作

以上为程序的运行的部分截图。

五、程序清单:

#define false 0

#define true 1

#include "stdio.h"

//#include <fcntl>

#include<string.h>

//#param warning(disable:4996)

FILE*x1,*x2;

typedef struct

{

char name[3]; /*文件或目录名*/ char type[2]; /*文件类型名*/ char attribute; /*属性*/ char address; /*文件或目录的起始盘块号*/ char length; /*文件长度,以盘块为单位*/ }content; /*目录结构*/

#define n 5 /*模拟实验中系统允许打开文件的最大数量*/ typedef struct

{

int dnum; /*磁盘盘块号*/ int bnum; /*盘块内第几项*/

}pointer; /*已打开文件表中读写指针的结构*/

typedef struct

{

char name[20]; /*文件绝对路径名*/ char attribute;/*文件的属性,用1个字节表示,所以用了char类型*/ int number; /*文件起始盘块号*/ int length; /*文件长度,文件占用的字节数*/ int flag; /*操作类型,用"0"表示以读操作方式开文件,用"1"表示写操作pointer read; /*读文件的位置,文件刚打开时dnum为文件起始盘块号,bnumpointer write; /*写文件的位置,文件建立时dnum为文件起始盘块号,bnum方式打开文件*/ 为"0"*/ 为"0",打开时为文件末尾*/

}OFILE; /*已打开文件表项类型定义*/

struct

{

char buffer1[64];/*模拟缓冲1*/

content buffer2[8];/*模拟缓冲2*/

FILE *fc; /*模拟磁盘的文件指针*/

void copen(OFILE *x1,OFILE *x2)

//OFILE *x1,*x2;

{

} strcpy(x1->name,x2->name); x1->attribute=x2->attribute; x1->number=x2->number; x1->length=x2->length; x1->flag=x2->flag; x1->read.dnum=x2->read.dnum; x1->read.bnum=x2->read.bnum; x1->write.dnum=x2->write.dnum; x1->write.bnum=x2->write.bnum; OFILE file[n]; /*已打开文件表*/ int length; /*已打开文件表中登记的文件数量*/ }openfile; /*已打开文件表定义*/

int sopen(char *name)

/*在已打开文件表中查找文件//P172

//char *name;

{

void dopen(char *name)

/*在已打开文件表中删除文件name*/

//char *name;

{

int iopen(content *x)

/*在已打开文件表中插入文件name*/

//content *x;

{ int i; i=sopen(name); if(i==-1) { } copen(&openfile.file[i],&openfile.file[openfile.length-1]); openfile.length--; printf("文件未打开\n"); else int i; i=0; while(i<openfile.length&&strcmp(openfile.file[i].name,name)!=0)/* i++; return(-1); name*/ 依次查找已打开文件表*/ if(i>=openfile.length) return(i); }/*查找sopen函数结束*/ }/*删除函数结束*/

int i; i=sopen(x->name); if(i!=-1) { } else if(openfile.length==n) { } else { } //copen(&openfile.file[openfile.length],x); openfile.length++; return(true); printf("已打开文件表已满\n"); return(false); printf("文件已经打开\n"); return(false); }/*填写已打开文件表函数结束*/

int allocate( )

/*分配一个磁盘块,返回块号*/ {

*/

//P173 int i; fseek(fc,0,SEEK_SET); /*将模拟磁盘的文件指针移至模拟磁盘FAT表*/ fread(buffer1,64L,1,fc);/*将FAT表中第一个磁盘块读入模拟缓冲for(i=3;i<63;i++) if(buffer1[i]==0) { /*FAT中的第i项为0,分配第i块磁盘块,修改FAT表,并且写回磁盘buffer1中*/ buffer1[i]=255;

} fseek(fc,0,SEEK_SET); fwrite (buffer1,64L,1,fc); return(i); /*返回磁盘号*/ fread(buffer1,64L,1,fc);/*将FAT表中第二个磁盘块读入模拟缓冲for(i=0;i<63;i++) if(buffer1[i]==0) {/*FAT中的第i项为0,分配第i+64块磁盘块,修改FAT表,并且写 } printf("已经没有磁盘空间\n"); return(false); buffer1[i]=255; fseek(fc,-64L,SEEK_CUR); fwrite(buffer1,64L,1,fc); return(i+64); /*返回磁盘号*/ buffer1中*/ 回磁盘*/ }/*分配磁盘块函数结束*/

int read_file(char *name,int length)

/*读文件函数,文件路径名name,读取长度length*/ //char *name;

//int length;

{

int i,t; //char ch; if((i=sopen(name))==-1) { } if(openfile.file[i].flag==1) { printf("文件以写方式打开,不能读\n"); printf("文件没有打开或不存在\n"); return (false);

} return 0; t=0; fseek(fc,openfile.file[i].read.dnum*64L,SEEK_SET); fread(buffer1,64,1,fc); while(t<length&&buffer1[openfile.file[i].read.bnum]!='#') { openfile.file[i].read.dnum=buffer1[openfile.file[i].read.dnum%64] } } t++; openfile.file[i].read.bnum=0; fseek(fc,openfile.file[i].read.dnum*64L,SEEK_SET); fread(buffer1,64,1,fc);/*读取下一个*/ putchar(buffer1[openfile.file[i].read.bnum]);/*读出一个字符(这if((t+1)%64==0)putchar('\n'); /*修改读指针*/ openfile.file[i].read.bnum++; if(openfile.file[i].read.bnum>=64)/*一块读完,读取下一个盘块*/ { fseek(fc,openfile.file[i].read.dnum/64*64, SEEK_SET); fread(buffer1,64,1,fc); 里是在屏幕上显示)*/ ;/*修改读指针*/ }/*读函数结束*/

int write_file(char *name,char *buff,int length) //P174

/*写文件函数*/

//char *name;/*文件路径名*/

//char *buff;/*存放准备写入磁盘的内容*/

//int length;/*写入内容的长度*/

{

int i,t,dd; if((i=sopen(name))==-1)/*文件不存在,无法写*/ { } if(openfile.file[i].flag==0) { } t=0; fseek(fc,openfile.file[i].write.dnum*64L, SEEK_SET); fread(buffer1,64,1,fc); while(t<length) { buffer1[openfile.file[i].write.bnum]=buff[t]; openfile.file[i].write.bnum++; openfile.file[i].length++; if(openfile.file[i].write.bnum>=64) { fseek(fc, openfile.file[i].write.dnum*64L, SEEK_SET); fwrite(buffer1,64,1,fc);/*一块写完,写回磁盘*/ if((dd=allocate())==false) { openfile.file[i].write.bnum--; openfile.file[i].length--; printf("无磁盘空间,部分信息丢失,写失败\n"); return (false); printf("文件以读方式打开,不能写\n"); return (false); printf("文件没有打开或不存在\n"); return (false); }/*if*/ fseek(fc,openfile.file[i].write.dnum/64*64L, SEEK_SET); fread(buffer1,64,1,fc); buffer1[openfile.file[i].write.dnum%64]=dd; fseek(fc,openfile.file[i].write.dnum/64*64L, SEEK_SET);

fwrite(buffer1,64,1,fc); openfile.file[i].write.dnum=dd; openfile.file[i].write.bnum=0; }/*if*/ t++; }/*while*/ fseek(fc, openfile.file[i].write.dnum*64L, SEEK_SET); fwrite(buffer1,64,1,fc);/*一块写完,写回磁盘*/ }/*写函数结束*/

int search(char *name,int flag,int *dnum,int *bnum)

/*查找路径名为name的文件或目录,返回该目录的起始盘块号 */

//char *name;

//int flag; /*flag=8表示查找目录,否则为文件*/

//int *dnum,*bnum;/*返回找到文件或目录的目录项的位置:盘块dnum中第bnum项*/

{

for(s=0;name[k]!='.'&&name[k]!='/'&&s<3&&name[k]!='\0';s++,k++) pna[s]=name[k]; pna[s]=' '; for(;s<3;s++)/*用空格补全名字长度*/ int k,i,s,j,last=0; char pna[3],type[2]; if((strcmp(name,"")==0)||(strcmp(name,"/")==0))/* return(2); 根目录*/ //P175 k=0; if(name[0]=='/')k=1; i=2; /*i=根目录的起始盘块号*/ while(last!=1) { /*pna=从name中分离出"/"后一个目录名(或文件名)*/

*/ & while(name[k]!='.'&&name[k]!='\0'&&name[k]!='/')/*除去多余字符 k++; type[0]=type[1]=' '; if(name[k]=='.')/*取文件类型名type*/ if(flag==8) { } else {/*文件遇到类型名认为结束,后面的字符作废*/ } else if(name[k]!='\0')k++; if(name[k]=='\0') last=1; /*查找目录且名字等于pna的目录项*/ fseek(fc,i*64L,SEEK_SET); fread(buffer2,64L,1,fc); j=0; if(last==1&&flag!=8) k++; if(name[k]!='\0')type[0]=name[k]; k++; if(name[k]!='\0')type[1]=name[k]; if(name[k]!='\0'&&name[k+1]!='\0') { } last=1; printf("文件名错误\n"); return(false); printf("目录不应该有有类型名,查找失败\n"); return(false); while(j<8&&!(buffer2[j].attribute!=8&&buffer2[j].name[0]==pna[0]&

j++; buffer2[j].name[1]==pna[1]&&buffer2[j].name[2]==pna[2]&& buffer2[j].type[0]==type[0]&&buffer2[j].type[1]==type[1])) else while(j<8&&!(buffer2[j].attribute==8&&buffer2[j].name[0]==pna[0]& &&buffer2[j].name[2]==pna[2])) j++; if(last==1)/*查找结束*/ { *dnum=i; *bnum=j; return(buffer2[j].address); &buffer2[j].name[1]==pna[1] if(j<8)/*找到该目录或文件*/ } else/*查找还未结束*/ i=buffer2[j].address;/*读取下一个盘块*/ return(false); else //P176 }/*while 查找结束*/ }/*search()结束*/

int create_file(char *name,int attribute)

/*建立文件函数,路径名name,文件属性attribute*/ //char *name;

//int attribute;

{

int i,j,k,s,d,t,b,dd,dn,bn; char dname[3],tname[2],pathname[20];

OFILE x; if(attribute%2==1) { } if(openfile.length==n) { } /* 将name分成两部分,目录路径pathname和目录名dname*/ for(j=0;name[j]!='\0';j++)/*查找最后一个“/”*/ if(name[j]=='/')s=j; /*分离目录路径*/ for(j=0;j<s;j++) pathname[j]=name[j]; pathname[j]='\0'; /*分离文件名*/ for(k=0,j=s+1;name[j]!='\0'&&k<3&&name[j]!='.';j++,k++) { } for(;k<3;k++) dname[k]=' '; k=0; if(name[j++]=='.')/*分离类型名*/ { } for(;k<2;k++) for(;name[j]!='\0'&&k<2&&name[j]!='.';j++,k++) tname[k]=name[j]; printf("错误文件名或目录名\n"); return(false); dname[k]=name[j]; if(k==0) printf("已打开表已满,不能建立\n"); return(false); printf("只读文件,无法写,不能建立\n"); return(false);

tname[k]=' '; if((d=search(pathname,8,&dn,&bn))==false)/*找到目录路径,返回该{ } /*确认该目录不存在的同时查找空目录项*/ printf("目录不存在,不能建立"); return(false); 目录所在块号dn和项数bn*/ b=-1; fseek(fc,d*64L,SEEK_SET); fread(buffer2,64L,1,fc); /*读出dnum盘块的内容*/ for(t=0;t<8;t++) { //P177 if(buffer2[t].name[0]==dname[0]&&buffer2[t].name[1]==dname[1]&&bu {/*找到名字dname的文件,建立失败*/ } if(buffer2[t].name[0]=='$'&&b==-1) b=t; printf("文件已经存在,不能建立\n"); return(false); ffer2[t].name[2]==dname[2] &&buffer2[t].type[0]==tname[0]&&buffer2[t].type[1]==tname[1]) }/*for*/ if(b==-1)/*没有空目录项,建立失败*/ { } if((dd=allocate( ))==false)/*分配给建立目录的磁盘盘块dd*/ { printf("建立文件失败\n"); return(false); printf("目录无空间\n"); return(false);

} /*填写目录项*/ for(i=0;i<3;i++) buffer2[b].name[i]=dname[i]; buffer2[b].type[i]=tname[i]; for(i=0;i<2;i++) buffer2[b].attribute=attribute; buffer2[b].address=dd; buffer2[b].length=0; fseek(fc,d*64L,SEEK_SET); fwrite(buffer2,64L,1,fc); /*填写已打开文件表*/ strcpy(x.name,name); x.attribute=attribute; x.number=dd; x.length=0; x.flag=1; x.read.dnum=x.write.dnum=dd; x.read.bnum=x.write.bnum=0; //iopen(&x); }/*建立文件结束*/

int open_file(char *name,int attribute) /*打开文件函数*/

//char *name;

//int attribute;

{

OFILE x; int dnum,bnum,last,i,d; if((d=search(name,4,&dnum,&bnum))==false) { } printf("文件不存在,打开操作失败\n"); return(false);

} fseek(fc,dnum*64L,SEEK_SET);/*fread(buffer2,64,1,fc); 读出对应目录项*/ //P178 if((buffer2[bnum].attribute%2==1)&& attribute==1)/*对只读文件要求{ } strcpy(x.name,name); x.attribute=buffer2[bnum].attribute; x.number=buffer2[bnum].address; x.read.dnum=x.write.dnum=buffer2[bnum].address; x.read.bnum=x.write.bnum=0; x.flag=attribute; if(attribute==1) { } iopen(&x);/*填写已打开文件表*/ while(d!='\xff')/*寻找文件末尾*/ { fseek(fc, d/64*64L, SEEK_SET); fread(buffer1,64L,1,fc);/*读出dnum项所在FAT*/ last=d; d=buffer1[d%64];/*读出dnum块下一块内容赋给dnum*/ printf("文件不能写,打开失败"); return(false); 写*/ }/*while*/ x.write.dnum=last;/*填写写指针*/ fseek(fc, last*64L, SEEK_SET); fread(buffer1,64L,1,fc); for(i=0;i<64&&buffer1[i]!='#';i++); x.write.bnum=i; x.length=(buffer2[bnum].length-1)*64+i;

int close_file(char *name)

/*关闭文件函数*/ //char *name; {

}

int Delete(char *name) /*删除文件*/

//char *name; int i,dnum,bnum; if((i=sopen(name))==-1) { } if(openfile.file[i].flag==1)/*写文件的追加文件结束符*/ { } /*在已打开文件表中删除该文件的登记项*/ fseek(fc,openfile.file[i].write.dnum*64L, SEEK_SET); fread(buffer1,64,1,fc); buffer1[openfile.file[i].write.bnum]='#'; fseek(fc,openfile.file[i].write.dnum*64L, SEEK_SET); fwrite(buffer1,64,1,fc); fputc('#',fc); search(name,4,&dnum,&bnum);/*查找该文件目录位置*/ /*修改目录中的文件长度*/ fseek(fc,dnum*64L, SEEK_SET); fread(buffer2,64,1,fc); buffer2[bnum].length=openfile.file[i].length/64+1; fseek(fc, dnum*64L, SEEK_SET); fwrite(buffer2,64,1,fc); printf("打开的文件中没有该文件,关闭失败\n"); return(false); if(openfile.length>1) copen(&openfile.file[i],&openfile.file[openfile.length-1]); //P179 openfile.length--;

{

int md(char *name)

/*建立目录函数,目录路径名name*/ //char *name;

{

int i,j,k,s,d,t,b,dd,dn,bn; int dnum,bnum,t; if((t=search(name,4,&dnum,&bnum))==false) { } if(sopen(name)!=-1) { } fseek(fc,dnum*64L, SEEK_SET); fread(buffer2,64,1,fc); buffer2[bnum].name[0]='$';/*将该文件的目录置成空目录*/ fseek(fc,dnum*64L, SEEK_SET); fwrite(buffer2,64,1,fc); while(t!='\xff')/*通过FAT查找每一个盘块号,并依次删除*/ { } dnum=t; fseek(fc, dnum/64*64, SEEK_SET); fread(buffer1,64,1,fc); t=buffer1[dnum%64]; buffer1[dnum%64]=0; fseek(fc, dnum/64*64L, SEEK_SET); fwrite(buffer1,64,1,fc); printf("该文件打开,不能删除\n"); return(false); printf("文件不存在\n"); return(false); }/*文件删除结束*/

char dname[3],pathname[20]; i=2;/* i=根目录的起始盘块号*/ /* 将name分成两部分,目录路径pathname和目录名dname*/ for(j=0;name[j]!='\0';j++)/*查找最后一个“/”*/ if(buffer2[t].name[0]==dname[0]&&buffer2[t].name[1]==dname[1] &&buffer2[t].name[2]==dname[2]&&buffer2[t].attribute==8) if(name[j]=='/')s=j; /*分离目录路径*/ for(j=0;j<s;j++) pathname[j]=name[j]; pathname[j]='\0'; /*分离目录名*/ for(k=0,j=s+1;name[j]!='\0'&&k<3&&name[j]!='.';j++,k++) { } for(;k<3;k++) { } b=-1; /*确认该目录不存在的同时查找空目录项*/ fseek(fc,d*64L,SEEK_SET); fread(buffer2,64L,1,fc);/*读出d盘块的内容*/ for(t=0;t<8;t++) { printf("目录不存在,不能建立\n"); return(false); dname[k]=' '; if((d=search(pathname,8,&dn,&bn))==false)/*找到目录路径*/ printf("错误文件名或目录名\n"); dname[k]=name[j]; if(k==0) return(false); //P180

{/*找到名字dname的目录,建立失败*/ } if(buffer2[t].name[0]=='$'&&b==-1) b=t; printf("目录已经存在,不能建立\n"); return(false); }/*for*/ if(b==-1)/*没有空目录项, 不能建立*/ { } if((dd=allocate( ))==false)/*分配给建立目录的磁盘盘块dd*/ { } /*填写目录项*/ for(i=0;i<3;i++) buffer2[b].name[i]=dname[i]; buffer2[b].type[0]=buffer2[b].type[1]=' '; buffer2[b].attribute=8; buffer2[b].address=dd; buffer2[b].length=0; fseek(fc,d*64L,SEEK_SET); fwrite(buffer2,64L,1,fc); /*分给新建目录的盘块初始化*/ for(t=0;t<8;t++) buffer2[t].name[0]='$'; fseek(fc, dd*64L, SEEK_SET); fwrite(buffer2,64L,1,fc); printf("目录不能建立\n"); return(false); printf("目录无空间\n"); return(false); }/*建立目录结束*/

int dir(char *name) /*显示目录内容*/

//char *name;

{

int t,dnum,dn,bn; if((dnum=search(name,8,&dn,&bn))==false)/*找到目录路径,返回该目录{ } printf("目录不存在\n"); return(false); 所在块号dn和盘块内项数bn*/ printf("名称 扩展名 起始盘块 长度\n"); /*显示目录内容*/ fseek(fc,dnum*64L, SEEK_SET); fread(buffer2,64L,1,fc); for(t=0;t<8;t++)/*显示该盘块中目录项的内容*/ if(buffer2[t].name[0]!='$') printf(" %c%c%c %c%c %4d%7d\n", buffer2[t].name[0], buffer2[t].name[2], buffer2[t].type[0], //P181 buffer2[t].name[1], buffer2[t].type[1],buffer2[t].address, buffer2[t].length);

}/*显示目录函数结束*/

char typefile(char *name)

/*显示文件内容*/

//char *name;

{

int dnum,dn,bn,t; if((dnum=search(name,1,&dn,&bn))==false) { } if(sopen(name)!=-1) { printf("文件不存在\n"); return(false);

} printf("该文件打开,不能显示\n"); return(false); while(dnum!='\xff') { } fseek(fc,dnum*64L,SEEK_SET); fread(buffer1,64,1,fc);/*读一个盘块到缓冲*/ for(t=0;t<64&&buffer1[t]!='#';t++)/*显示缓冲中内容*/ putchar(buffer1[t]); printf("\n"); /*获得下一个盘块*/ fseek(fc, dnum/64*64L, SEEK_SET); fread(buffer1,64,1,fc); dnum=buffer1[dnum%64]; }/*显示文件函数结束*/

int change(char *name,int attribute) /*改变文件name的属性为attribute*/ //char *name;

//int attribute;

{

int dnum,bnum; if(search(name,1,&dnum,&bnum)==false)/*查找文件目录*/ { } if(sopen(name)!=-1) { } fseek(fc,dnum*64L,SEEK_SET); printf("该文件打开,不能改变文件属性\n"); return(false); printf("文件不存在\n"); return(false); //P182

fread(buffer2,64,1,fc);/*读出该目录所在盘块*/ buffer2[bnum].attribute=attribute;/*修改属性*/ fseek(fc,dnum*64L,SEEK_SET); fwrite(buffer2,64,1,fc);/*写回磁盘*/ }/*改变文件属性函数结束*/

int main( ) {

char name[20]; //FILE*x1,*x2; //errno_t err; //char err; int attribute,type,length,i,a,j; char buffer[64]; /*建立文件,模拟磁盘*/ if((fc=fopen("c:\c","w+"))==NULL)// { } /*初始化已打开文件表*/ openfile.length=0; /*初始化磁盘*/ /*初始化文件分配表*/ buffer1[0]=buffer1[1]=buffer1[2]=255;/*磁盘第0、1块存放FAT表,第for(i=3;i<64;i++) buffer1[i]=0; buffer1[13]=buffer1[49]=254;/*假定模拟磁盘中有两个坏盘块:第13块fwrite(buffer1,64L,1,fc); for(i=0;i<64;i++) buffer1[i]=0; printf("无法打开文件\n"); exit(0); 2块存放跟目录*/ 和49块*/ //P183

fwrite(buffer1,64L,1,fc); /*初始化根目录*/ for(i=0;i<8;i++) buffer2[i].name[0]='$';/*若目录项的第一个字符为“$”表示该目录项为空*/ fwrite(buffer2,64L,1,fc); /*初始化已打开文件表*/ while(1) { printf("\n 0 - 结束\n"); printf(" 1 - 建立文件\n"); printf(" 2 - 打开文件\n"); printf(" 3 - 读文件\n"); printf(" 4 - 写文件\n"); printf(" 5 - 关闭文件\n"); printf(" 6 - 删除文件\n"); printf(" 7 - 建立目录\n"); printf(" 8 - 显示目录内容\n"); printf(" 9 - 显示文件内容\n"); printf(" 10 - 改变文件属性\n"); printf(" 选择功能项(0~9):"); scanf("%d",&a); switch(a) { case 0: /*a=0程序结束*/ fclose(fc); exit(0); printf("输入文件路径名和文件属性(1-只读文件,3-只读系统文scanf("%s%d",name,&attribute); create_file(name,attribute); /*建立文件*/ break; case 1: /*a=1建立文件*/ 件,4-普通文件):"); case 2: /*a=2打开文件*/

printf("输入文件路径名和操作类型(0-读文件,1-写文件):"); scanf("%s%d",name,&type);

open_file(name,type); /*打开文件*/

break;

case 3: /*a=3读文件*/

printf("输入文件路径名和读长度");

scanf("%s%d",name,&length);

read_file(name,length); /*读文件*/

break;

case 4: /*a=4写文件*/

printf("输入文件路径名:");

scanf("%s",name);

printf("输入写的内容和和写长度");

scanf("%s%d",buffer,&length);

write_file(name,buffer,length); /*写文件*/

break;

case 5: /*a=5关闭文

//P184

printf("输入文件路径名");

scanf("%s",name);

close_file(name); /*关闭文件*/

break;

case 6: /*a=6删除文件*/

printf("输入文件路径名");

scanf("%s",name);

Delete(name); /*删除文件*/

break;

case 7: /*a=7建立目录*/

printf("输入目录路径名");

scanf("%s",name);

md(name); /*建立目录*/

break;

case 8: /*a=8显示目录*/

printf("输入目录路径名");

scanf("%s",name); 件*/

dir(name); /*显示目录*/ break; printf("输入文件路径名"); scanf("%s",name); typefile(name); /*显示文件*/ break; printf("输入文件路径名和文件属性(1-只读文件,3-只读系统文scanf("%s%d",name,&attribute); change(name,attribute); case 9: /*a=9显示文件*/ case 10:/* a=10改变文件属性 */ 件,4-普通文件):"); }/* switch */

)结束}/* while */ }/*main(

//P185

六、结束语: */

通过对磁盘文件操作,使我了解了基本的磁盘文件的知识,再加上对程序流程的理解,更加明白了Windows对磁盘管理的方式,首先程序查找绝对路径名name,然后从name中分离出“/”后下一个目录(或文件名);若是文件,分离出类型名type,再进行之后的判断操作。当在已打开的文件表中查找某文件时,首先查找文件路径名为pname的文件,通过一个变量的判断,进行查找。将某文件从已打开的表中删除时,在已打开的文件表中查找路径名为name的登记项i,如果找到该文件登记项i,删除第i项,如果没有找到,提示文件没有打开,删除失败。通过对这些流程的理解,让我深刻的体会到了磁盘文件操作的步骤,达到了实习目的。

参考文献:

[1] 滕艳平等.计算机操作系统(实验指导书),哈尔滨工业大学出版社.20xx年

9月

[2] 张明等编.操作系统习题解答与实验指导(第二版).中国铁道出版社.2007

年12月

[3] 张丽芬等编.操作系统实验教程.清华大学出版社.20xx年

[4] 张献忠等编.操作系统学习辅导.清华大学出版社.20xx年

[5] 汤小丹等编.计算机操作系统.西安电子科技大学出版社.20xx年9月

更多相关推荐:
操作系统实习报告

操作系统实习报告题目基于shell的形式来模拟文件系统班级学号姓名11学年12学年第2学期操作系统实习报告书专业班级姓名学号实习地点辅导教师实习内容基于shell的形式来模拟文件系统实习环境Windows操作系...

操作系统实验报告 完全版

《计算机操作系统》实验报告班级:姓名:学号:实验一进程控制与描述一、实验目的通过对Windows2000编程,进一步熟悉操作系统的基本概念,较好地理解Windows2000的结构。通过创建进程、观察正在运行的进…

计算机操作系统实训报告

计算机操作系统实训报告册学期20xx20xx第二学期课程计算机操作系统实训专业计算机科学与技术班级学号姓名指导教师张治国实训习报告评语I等级评阅人职称年月日河南工程学院实训习报告II实训目的内容理解操作系统的地...

高级操作系统实习报告一

目录实习报告2一Linux流行版本的发展历史及简介21Fedora22redhat23centos34ubuntu45Debian56openSUSE6二linux的安装6三文件系统的组织结构7四Linux的系...

操作系统实习报告 -1

操作系统实习报告日期附代码importjavautilconcurrentSemaphorepublicclassreaderfirstSemaphoremutexnewSemaphore1提供互斥reader...

操作系统实训报告

河南工程学院计算机学院计算机操作系统实训报告册学期20xx20xx第二学期课程计算机操作系统实训专业计算机科学与技术班级班学号20xx1091姓名指导教师张治国实训习报告评语等级评阅人年月职称日河南工程学院实训...

操作系统实习报告

操作系统实习报告题目处理器调度专业班级网络112班学生陈宇鹏学号3110757214实验一处理器调度一实习内容选择一个调度算法实现处理器调度二实习目的在采用多道程序设计的系统中往往有若干个进程同时处于就绪状态当...

实训报告2视窗操作系统 3

实训报告2视窗操作系统项目题目1玩转WINDOUWS项目类型2综合型项目目的3能将一台裸机安装成一台能胜任学习工作和娱乐的全能机4掌握WindowsXP系统的安装的安装方法和硬件驱动程序的安装方法56789掌握...

操作系统上实验报告3

操作系统实验三报告实验题目进程管理及进程通信实验环境虚拟机Linux操作系统实验目的1利用Linux提供的系统调用设计程序加深对进程概念的理解2体会系统进程调度的方法和效果3了解进程之间的通信方式以及各种通信方...

操作系统实验报告

一实验内容模拟时钟中断的产生及设计一个对时钟中断事件进行处理的模拟程序二实验目的现代计算机系统的硬件部分都设有中断机构它是实现多道程序设计的基础中断机构能发现中断事件且当发现中断事件后迫使正在处理器上执行的进程...

操作系统实验报告

操作系统实验报告,内容附图。

操作系统实验报告

武汉理工大学学生实验报告书实验课程名称操作系统开课学院计算机科学与技术学院指导老师姓名学生姓名学生专业班级20xx20xx学年第一学期实验课程名称操作系统实验课程名称操作系统实验课程名称操作系统实验课程名称操作...

操作系统实习报告(19篇)