文件管理实验报告

时间:2024.4.20

文件管理

一、实验目的

1.了解os中文件的组织和管理。

2.熟悉文件中所用的数据结构。

二、实验要求

1.    设计一个N个用户的文件系统,每个用户最多保存m个文件。 

2.    限制用户在一次使用中只能打开L个文件。

3.    系统应能检查输入命令的正确性,出错能显示出原因。

4.    对文件必须设置保护措施,如只读、写、执行等。在每次打开时再次设置保护级别,即可有二级保护。

5.    对文件的操作至少有以下几条命令

         create:建文件

         delete:删文件

         open:打开文件

         close:关闭文件

         read:读文件

         write:写文件

举例:主文件目录

       mfd=record

username :string[maxlen];

files    :array[1..L] of ufd;

ofiles   :arrau[1..S] of uod

end;

用户打开文件目录表:

uod=record

    filename:string[maxlen];

    attrib:attrib;

    len:integer;

    status:(open,create);

    rp,up:integer;

end;

用户文件目录:

  ufd=record

    fielname:string[maxlen];

    attrib?ro,rw);

    len:integer;

    addr:integer;

  end;

流程图:

文件管理实验报告

二、主要数据结构

界面采用VC6 MFC环境开发

#define MAXFILE 20   //每个用户最多保存20个文件

#define MAXUSER 10   //假想文件系统最多支持的人数

#define BLOCKSIZE 32 //虚拟磁盘中物理块为每块32字节

#define DISKSIZE BLOCKSIZE*1000  //虚拟磁盘容量为1000*32=32K

struct UFD  //说明文件项的结构数组

{

            char FileName[15];

            char Time[16];      //文件建立或修改时间  如2003/5/6 12:00

            bool IsExist;      //文件是否存在,删除时标为0

            bool IsShared;      //共享标记,共享文件可被其它用户所访问

            bool AttrRead;      //文件是否可读

            bool AttrWrite;     //文件是否可写

            bool AttrExecute;   //文件是否可执行

            HTREEITEM treeNode; //用于树控件显示的结点句柄

            USHORT FileLen;     //文件占用字节数

            USHORT BlockNum;   //文件占用的物理块数

            USHORT FileLink[100];//文件物理块地址数组,每块32字节,限定一个文件最大100*32=3200字节

};

struct MFD

{

            char UserName[10];  //主目录用户名

            bool IsExist;      //该用户否存在

            UFD ufd[MAXFILE];   //用户文件数组 

            USHORT nItem;//UFD个数

};

struct HEADBLOCK

{

            BYTE pStack;    //堆栈指针

            SHORT pBlock[10]; //块号   pBlock[10]是下一个盘块号逻辑地址

};

struct BLOCK          //虚拟磁盘的物理块数据结构

{

   union{

               BYTE block[32];        //一块为32字节

               HEADBLOCK HeadInfo;

            };

};

struct FAT

{

            BLOCK  SuperBlock;     //超级块,指示第一个空闲块逻辑号

            USHORT MaxOpen;       //该用户同时可打开的最大文件数

            USHORT UserNum;       //最户数

            MFD    Mfd[MAXUSER];  //最多可支持10个用户

};

//空闲块成组链接法

bool OpenList[MAXUSER][MAXFILE]; //描述文件是否打开的布尔型数组

FAT FileFAT;            //描述文件记录项的FAT结构

CFile FATIO;                      //负责和VDISK.DAT打交道的文件句柄

CString CurrentUser;              //当前登录的用户名

Int     CurrentID;                //前前登录的用户标识号

说明:本实验采用模拟文件结构的方法,把记录用户帐号,用户文件和磁盘块的信息用当前目录下的VDISK.DAT来记录,可以把VDISK.DAT看成是一个虚拟的磁盘,其头部是FAT结构,用来记录各个用户和文件信息,紧接着是空闲块成组链接法的数据结构,每块32字节,每组10块,共1000块,也就是说,用户文件数据的总容量是32*1000字节,如果程序当前目录下找不到用于做实验用的VDISK.DAT,在登录时程序会提示是否“格式化虚拟磁盘”也就是新建一个VDISK.DAT文件,接着,程序会显示“用户管理”的窗口,此时应新建几个帐号用于登录做实验。

登录后,程序会显示该用户的所有文件,右方的文件列表会显示每个文件的属性信息,和WINDOWS的“资源管理器”相似。用鼠标双击列表的每个文件就可以查看文件的内容。单击“新建文件”按钮可以创建一个新的用户文件。

选中某个文件后,就可以进行相应的操作,如“修改文件”、“删除文件”或是“打开文件”,删除某个文件时检查该文件的属性,如果是只读的,就是显示警告窗口让用户确认是否一定要删除。

硬盘工具可以用图形方式显示“磁盘”块的详细情况,空白块说明该块没有使用,暗红色的说明块已分配,窗口还统计占用的空间大小、用户数等信息。

程序中用到的结构图如下图所示:

MFD   

文件管理实验报告

文件管理实验报告

文件管理实验报告

三、主要算法与部分代码

void CDlgUser::OnAddUser()

{

    UpdateData(true);

if (FileFAT.UserNum>=10)

{

AfxMessageBox("用户数量已达到最大10个,你可以删除一些无用的帐号!");

return;

}

     for(int i=0;i<10;i++)

{

if(FileFAT.Mfd[i].IsExist==false)

{

              wsprintf(FileFAT.Mfd[i].UserName,m_UserName);

              FileFAT.Mfd[i].IsExist=true;

              FileFAT.Mfd[i].nItem=0;

              break;

}

}

FileFAT.UserNum++;

      WriteFAT();

ReadFAT();

ShowUser();//显示现有的用户列表

m_UserName.Empty();

UpdateData(false);

}

bool ReadBlock(int id, BLOCK* buffer)  //读指定块号内容(32字节)到buffer所指向的单元

{

if(!FATIO) return false;  //如果虚拟磁盘文件句柄为空,出错返回

if(!FATIO.Seek(sizeof(FAT)+(id-1)*BLOCKSIZE,CFile::begin)) return false;//移动文件指针到指定块号

if(FATIO.Read(buffer,BLOCKSIZE)!=BLOCKSIZE) return false;//读该块的内容到buffer指定的单元

return true;

}

bool WriteBlock(int id, BLOCK* buffer)  //把buffer所指向的单元的内容(32字节)写到指定的物理块中

{

    if(!FATIO) return false;  

if(!FATIO.Seek(sizeof(FAT)+(id-1)*BLOCKSIZE,CFile::begin)) return false;

    FATIO.Write(buffer,BLOCKSIZE);

    return true;

}

USHORT AllocBlock()    //分配一物理块,成功返回逻辑块号,失败返回0;

{

     if(!FileFAT.SuperBlock.HeadInfo.pBlock[FileFAT.SuperBlock.HeadInfo.pStack]) return 0; 

//没有空间可分配,失败返回

 if(FileFAT.SuperBlock.HeadInfo.pStack<9)//如果一组的空闲块没有分配完

 {

WriteFAT();

//将返回超级块所指的空闲块,再将堆栈指针加一

return FileFAT.SuperBlock.HeadInfo.pBlock[FileFAT.SuperBlock.HeadInfo.pStack++];

}

else  //如果分配的空闲块是组头

{

         WriteFAT();

USHORT returnBlock=FileFAT.SuperBlock.HeadInfo.pBlock[9];

//将要分配的组头复制到超级块,再返回组头作为空闲块

 if(!ReadBlock(returnBlock,&FileFAT.SuperBlock)) return 0;

return  returnBlock;

 }

    WriteFAT();

 return 0;

}

bool FreeBlock(USHORT BlockID)  //回收一物理块,成功返回TRUE,失败返回FALSE

{

    if(FileFAT.SuperBlock.HeadInfo.pStack>0)//如果该组的空闲没有回收满

{

           //堆栈指针退一,把回收的块号记入超级块

FileFAT.SuperBlock.HeadInfo.pBlock[--FileFAT.SuperBlock.HeadInfo.pStack]=BlockID;

   BLOCK newBlock;

 //把回收的块内容清空

  if (!WriteBlock(BlockID,&newBlock)) return false;

}

else//如果该组已回收满,需要加入一新组的话

{

       if (!WriteBlock(BlockID,&FileFAT.SuperBlock)) return false;//将超级块的栈内容复制到要回收的块中

                   FileFAT.SuperBlock.HeadInfo.pStack=9;//将超级块的栈指针指向回收的块

                   FileFAT.SuperBlock.HeadInfo.pBlock[9]=BlockID;

}

WriteFAT();

return true; 

}

bool ReadFAT()  //从虚拟磁盘中读取FAT结构信息到FileFAT中

{

ZeroMemory(&FileFAT,sizeof(FileFAT));

 FATIO.SeekToBegin();

    if (!FATIO.Read(&FileFAT,sizeof(FileFAT))) return false;

return true;

}

bool Format()   //格式化虚拟磁盘,创建VDISK.DAT,所有用户和文件信息将被清空!

{

    CString FATFile;

 int i;

 char fname[128];

GetCurrentDirectory(128,fname);   //FAT表信息保存在当前目录的VDISK.DAT中

FATFile.Format("%s",fname);

 if (FATFile.Right(1)!="\\")

FATFile+="\\VDISK.DAT";

 else

         FATFile+="VDISK.DAT";

 CFile fout;

 if( !fout.Open(FATFile,CFile::modeCreate|CFile::modeWrite,NULL))

return false;

 ZeroMemory(&FileFAT,sizeof(FileFAT));

 FileFAT.SuperBlock.HeadInfo.pStack=0;

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

 {

        FileFAT.SuperBlock.HeadInfo.pBlock[i]=i+1;

 }

 fout.WriteHuge(&FileFAT,sizeof(FileFAT));

 BYTE *Buffer;

 Buffer=(BYTE*)malloc(DISKSIZE);//申请成组链接法所需的磁盘块空间

    ZeroMemory(Buffer,DISKSIZE);

 BLOCK newBlock;

for (i=10;i<=990;i+=10)

 {

  ZeroMemory(&newBlock,sizeof(newBlock));

 newBlock.HeadInfo.pStack=0;

 for (int k=0;k<10;k++)

newBlock.HeadInfo.pBlock[k]=i-9+k;

  memcpy(Buffer+32*(i-1),&newBlock,32);

 }

fout.WriteHuge(Buffer,DISKSIZE); //将格式化的块信息写入VDISK.DAT

 free(Buffer);

  fout.Close();

 AfxMessageBox("创建虚拟磁盘文件成功!请选择用户管理添加新用户。");

 return true;

}

//StartIO()用于完成与虚拟磁盘的IO的初始化工作

void StartIO() //打开VDISK.DAT文件,把该文件句柄保存在全局变量中,如果该文件不存在,创建并初始化该文件。

{

     CString FATFile;

 char fname[128];

GetCurrentDirectory(128,fname);   //FAT表信息保存在当前目录的VDISK.DAT中

 FATFile.Format("%s",fname);

 if (FATFile.Right(1)!="\\")

 FATFile+="\\VDISK.DAT";

 else

         FATFile+="VDISK.DAT";

 bFormated=true;

 if (!FileExist(FATFile))

{

 AfxMessageBox("当前目录下找不到VDISK.DAT,该文件是用来模拟磁盘及文件管理表。\n单击确定创建新的虚拟磁盘文件!");

 bFormated=false;

 if (!Format())

 {

 AfxMessageBox("创建文件系统出错!");

 return;

 }

 }

 if(!FATIO.Open(FATFile,CFile::modeReadWrite|CFile::shareDenyWrite,NULL))

 {

            AfxMessageBox("调入FAT表失败,文件系统可能出错!");

  bFormated=false;

  return;

 }

}

bool CreateNewFile(CString FileName, CString FileContent, bool AttrRead, bool AttrWrite, bool AttrExecute, bool AttrShare)  //创建一个新文件

{

    if (FileNameExist(FileName)) return false;  //如果要建立的文件与现有文件重名,失败返回

int i,FilePos,FileLen,BlockNum,BlockID;

bool flag=false;

FileContent.TrimLeft();FileContent.TrimRight();

FileLen=FileContent.GetLength();

char Content[32];//把文件内容分割成每个物理块大小后送content字符数组,以备写入磁盘块中

for(i=0;i

{

 if(!FileFAT.Mfd[CurrentID].ufd[i].IsExist)//扫描所有文件项,如果标记不存在就准备写入新建文件信息

      {

 flag=true;FilePos=i;

        break;

   }

}

    if(!flag) return false;

BlockNum=(int)FileLen/BLOCKSIZE+1;//计算文件占用的块数

  for(i=0;i

{

BlockID=AllocBlock();//得到分配的块的逻辑号

       if(BlockID)

   {

 FileFAT.Mfd[CurrentID].ufd[FilePos].FileLink[i]=BlockID;//逐个将块号记入文件项中

wsprintf(Content,FileContent.Mid(i*32,32));//写入一个块的内容到缓冲区

if(!WriteBlock(BlockID,(BLOCK*)Content)) return false;//从缓冲区写到虚拟磁盘

    }

else

{

return false;

}

}

//以下是填写文件的属性,时间等信息

wsprintf(FileFAT.Mfd[CurrentID].ufd[FilePos].FileName,FileName.Left(15));

    FileFAT.Mfd[CurrentID].ufd[FilePos].IsExist=true;

FileFAT.Mfd[CurrentID].ufd[FilePos].BlockNum=BlockNum;

FileFAT.Mfd[CurrentID].ufd[FilePos].AttrExecute=AttrExecute;

    FileFAT.Mfd[CurrentID].ufd[FilePos].AttrRead=AttrRead;

FileFAT.Mfd[CurrentID].ufd[FilePos].AttrWrite=AttrWrite;

FileFAT.Mfd[CurrentID].ufd[FilePos].IsShared=AttrShare;

    FileFAT.Mfd[CurrentID].ufd[FilePos].FileLen=FileContent.GetLength();

wsprintf(FileFAT.Mfd[CurrentID].ufd[FilePos].Time,GetCurrentTime());

FileFAT.Mfd[CurrentID].nItem++;

WriteFAT();

ShowUserFiles();//刷新用户文件列表,以便将新建的文件显示出来

return true;

}

CString ReadFile(CString FileName)  //给定当前用户的文件名,将文件内容以Cstring字符串返回

{

    int i,FilePos;

bool flag=false;

char Buffer[32];

CString strReturn;

for(i=0;i

{

if(FileFAT.Mfd[CurrentID].ufd[i].FileName==FileName&&FileFAT.Mfd[CurrentID].ufd[i].IsExist==true)

{

flag=true;FilePos=i;break;

}

}

if(!flag) return "";

for(i=0;i

{

ZeroMemory(Buffer,32);

if(!ReadBlock(FileFAT.Mfd[CurrentID].ufd[FilePos].FileLink[i],(BLOCK*)Buffer)) return "";

strReturn+=Buffer;

}

return strReturn;

}

bool KillFile(CString FileName)//根据文件名删除用户当前文件

{

    int i,FilePos;

bool flag=false;

for(i=0;i

{

if(FileFAT.Mfd[CurrentID].ufd[i].FileName==FileName&&FileFAT.Mfd[CurrentID].ufd[i].IsExist==true)

{

                flag=true;  FilePos=i;      break;

}

}

if(!flag) return false;

for(i=0;i

if(!FreeBlock(FileFAT.Mfd[CurrentID].ufd[FilePos].FileLink[i])) return false;

FileFAT.Mfd[CurrentID].nItem--;

     ZeroMemory(&FileFAT.Mfd[CurrentID].ufd[FilePos],sizeof(UFD));

     WriteFAT();

    return true;

}

bool ModifyFile(CString FileName, CString FileContent, bool AttrRead, bool AttrWrite, bool AttrExecute, bool AttrShare)     //修改文件,包括文件名、属性和内容

{

    int i,FilePos,BlockNum,BlockID;

    bool flag=false;

FileContent.TrimLeft();

FileContent.TrimRight();

char Content[32];

for(i=0;i

{

if(FileFAT.Mfd[CurrentID].ufd[i].FileName==SelectedFileName)

{

flag=true; FilePos=i;break;

}

}

    if(!flag) return false;

for(i=0;i

{

if(!FreeBlock(FileFAT.Mfd[CurrentID].ufd[FilePos].FileLink[i])) return false;

}

      ZeroMemory(&FileFAT.Mfd[CurrentID].ufd[FilePos].BlockNum,200);

BlockNum=(int)FileContent.GetLength()/BLOCKSIZE+1;

      for(i=0;i

{

BlockID=AllocBlock();

         if(BlockID)

{

                FileFAT.Mfd[CurrentID].ufd[FilePos].FileLink[i]=BlockID;

            wsprintf(Content,FileContent.Mid(i*32,32));

                if(!WriteBlock(BlockID,(BLOCK*)Content)) return false;

}

else

{

                return false;

}

}

wsprintf(FileFAT.Mfd[CurrentID].ufd[FilePos].FileName,FileName.Left(15));

       FileFAT.Mfd[CurrentID].ufd[FilePos].IsExist=true;

FileFAT.Mfd[CurrentID].ufd[FilePos].BlockNum=BlockNum;

FileFAT.Mfd[CurrentID].ufd[FilePos].AttrExecute=AttrExecute;

       FileFAT.Mfd[CurrentID].ufd[FilePos].AttrRead=AttrRead;

FileFAT.Mfd[CurrentID].ufd[FilePos].AttrWrite=AttrWrite;

FileFAT.Mfd[CurrentID].ufd[FilePos].IsShared=AttrShare;

    FileFAT.Mfd[CurrentID].ufd[FilePos].FileLen=FileContent.GetLength();

wsprintf(FileFAT.Mfd[CurrentID].ufd[FilePos].Time,GetCurrentTime());

WriteFAT();

ShowUserFiles();

return true;

}

void CDlgDisk::CalcBlock()// “磁盘工具”中的计算并显示磁盘块使用情况功能

{

     BYTE DiskImage[32000];//磁盘数据区所有物理块映像数组

 FATIO.Seek(sizeof(FileFAT),CFile::begin);//跳过FAT结构,定位文件指针至数据区物理块头

 FATIO.Read(&DiskImage,32000);//读物理块映像

register sum=0;//保存使用的总块数

for(int i=0;i

 {

       m_ctrlChecker.SetBlock(FileFAT.SuperBlock.HeadInfo.pBlock[i]-1, RGB(200, 0, 0));

 sum++;

 }

 BLOCK testBlock;

 memcpy(&testBlock,&DiskImage[FileFAT.SuperBlock.HeadInfo.pBlock[9]*32],BLOCKSIZE);

    while(testBlock.HeadInfo.pBlock[9]>0)

 {

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

 {

             m_ctrlChecker.SetBlock(testBlock.HeadInfo.pBlock[i]-1, RGB(200,0,0));

             sum++;

 }

  memcpy(&testBlock,&DiskImage[testBlock.HeadInfo.pBlock[9]*32],BLOCKSIZE);

 }

 AddPiece(RGB(200,0,0),(int)sum*360/100,"Used");  

 m_Used.Format("已用空间:%d 字节",sum*32);

m_UserNum.Format("用户数:%d",FileFAT.UserNum);

 UpdateData(false);

}

更多相关推荐:
操作系统 实验报告 文件管理

昆明理工大学信息工程与自动化学院学生实验报告201201学年第二学期课程名称操作系统开课实验室年月日一实验目的用C或C语言编写和调试一个简单的文件系统模拟文件管理的基本功能从而对各种文件操作命令的实质内容和执行...

文件目录管理实验报告

OS课程设计采用二级目录实现文件管理操作系统课程设计报告采用二级目录实现文件管理学院信息工程学院班级计科1002班姓名杨辉学号101304230指导教师邹姝稚时间20xx年1月成绩117OS课程设计采用二级目录...

操作系统实验报告 文件管理系统 源程序

操作系统实验报告操作系统实验报告题目班级文件管理系统20xx年12月21日1操作系统实验报告目录一实践内容311实验内容32实验原理43实验要求4二实验的目的及意义4三详细设计531功能设计532结构设计633...

文件管理实验报告

实验题目文件管理一实验目的本实验模拟操作系统中的建立文件删除文件建立目录显示目录改变目录和删除目录等操作通过该实验使学生了解文件系统的基本结构和文件的各种管理方法二实验原理文件通常存放在外存如磁盘磁带上可以作为...

文件管理系统实验报告

华中师范大学计算机科学系实验报告书实验题目基于两级目录结构的简单文件系统的管理与操作课程名称操作系统主讲教师辅导教师叶俊民教授班级1班实验时间20xx年12月10日目录CDIO性质的实践步骤2构思性实践C做什么...

【电大本科操作系统实验报告】文件管理

1234567

实验三操作系统文件管理实验报告

计算机导论实验3实验报告实验3操作系统文件管理班级学号姓名1DOS目录文件夹和文件1快速测试问题的总结报告2Explore中123456789102Windows目录文件夹和文件1快速测试问题的总结报告2123...

操作系统文件管理实验报告

实验报告课程名称计算机操作系统实验名称班级学号姓名成绩指导教师赵安科实验日期20xx年6月18日一实验题目文件管理二实验内容模拟文件存储空间的管理采用空白文件目录法和空白块链法实施空间分配三实验说明文件存储空间...

实验3 操作系统文件管理实验报告

计算机导论实验3实验报告实验3操作系统文件管理班级学号姓名1DOS目录文件夹和文件1说明以下命令的功能adir命令bcd命令cmkdir命令dcopy命令eecho命令fcopy命令gdel命令hrd命令提示可...

文件或文件夹管理实验报告

实验二文件和文件夹的管理一实验目的通过本实验掌握文件和文件夹的组织和管理二实验任务文件文件夹的建立复制移动删除重命名更改文件或文件夹的属性三实验过程1练习一1重命名练习把文件READMEtxt改名为HELPtx...

实验报告-文件管理与资源共享

Windows管理课程班级姓名实训项目完成日期实训报告一实训目的二实训要求1在C盘根目录下创建share文件夹并共享该文件夹共享名为webshare共享权限设置为只读2继续共享share文件夹共享名为wwwsh...

实验四 文件管理报告

昆明理工大学信息工程与自动化学院学生实验报告20xx20xx学年第二学期一实验目的用C或C语言编写和调试一个简单的文件系统模拟文件管理的基本功能从而对各种文件操作命令的实质内容和执行过程有比较深入的了解二实验原...

文件管理实验报告(33篇)