现在的位置: 首页 > 综合 > 正文

【OS课程设计二】模拟DOS系统文件的物理结构和管理使用

2013年09月11日 ⁄ 综合 ⁄ 共 13443字 ⁄ 字号 评论关闭

一、设计目的

1、模拟DOS系统文件的建立和使用情况,理解磁盘文件的物理结构
2、深入理解文件的物理结构与存取方法之间的关系
二、设计要求
1、模拟设计DOS系统中磁盘文件的存储结构
假定磁盘存储空间共有l00个物理块,设计一个FAT表。FAT表可用一个一维数组定义,其中每一个数组元素与一个物理块对应。当第i个元素为0时,表示第i盘块空闲;当第i个元素为-1时,其值表示一个文件结束标志;当第i个元素为其他数值时,其值表示该文件的下一物理块号。初始化时FAT标的所有元素均为0。另外,再设一个空闲块总数变量,记录系统还剩的空闲块数。它的值和FAT表中值为0的元素个数应该一致。
设计磁盘文件目录,每个文件保存:文件名、起始盘块号、长度(占盘块数)三个信息。
2、模拟设计文件存储时磁盘空间的分配过程
(1) 假定一个物理块的容量是1024B,要求设计一个程序,把文件的流式逻辑结构转换成链接物理结构:当用户要求将文件保存在磁盘上时,给出文件名及文件的长度,系统应能在磁盘上正确地为其分配存储空间,保存文件,改写FAT表和磁盘文件目录。这个程序形成一个键盘命令: write(文件名,文件长度)
(2) 要求设计另一个程序,当用户改写了文件后给出文件名及文件的长度,要求重新保存文件时,系统应能将文件原占有的盘块按其原有的逻辑顺序分配给该文件,保存文件。如果改写后的文件短于原文件,则回收它原来占有的倒数若干个盘块;如果改写后的文件长于原文件,则要为它增加分配若干个盘块。重新保存文件后要改写FAT表和磁盘文件目录。这个程序形成一个键盘命令: rwrite(文件名,文件长度)
3、模拟设计文件存储时磁盘空间的回收过程
要求设计第三个程序,当用户要求删除指定文件时,系统应能改写FAT表,回收该用户文件占用的磁盘空间,并删除该文件的目录信息。这个程序形成一个键盘命令: dele(文件名)
设计上述三条指令,在文件保存、删除后显示FAT表和磁盘文件目录。
在磁盘空间分配、回收的过程中,注意检查盘块使用情况的数据一致性。

Dir_Entry.h

Code:
  1. #ifndef _DIR_ENTRY_H_   
  2. #define _DIR_ENTRY_H_   
  3. #include <string>   
  4.   
  5.     using std::string;   
  6.        
  7.     class Dir_Entry   
  8.     {   
  9.     public:   
  10.         Dir_Entry(string fn,unsigned int fs,unsigned int sn):file_name(fn),first_sector(fs),sector_num(sn){}   
  11.            
  12.         string get_File_Name() const  
  13.         {   
  14.             return file_name;   
  15.         }   
  16.            
  17.         unsigned int get_First_Sector() const  
  18.         {   
  19.             return first_sector;   
  20.         }   
  21.            
  22.         unsigned int get_Sector_Num() const  
  23.         {   
  24.             return sector_num;   
  25.         }   
  26.            
  27.         void set_Sector_Num(unsigned int sn)   
  28.         {   
  29.             sector_num = sn;   
  30.         }   
  31.            
  32.     private:   
  33.         string file_name;   
  34.         unsigned int first_sector;   
  35.         unsigned int sector_num;   
  36.     };   
  37.   
  38. #endif   

Disk_Routine.h

Code:
  1. #ifndef _DISK_ROUTINE_H_   
  2. #define _DISK_ROUTINE_H_   
  3. #include <vector>   
  4. #include <list>   
  5. #include <string>   
  6. #include "Dir_Entry.h"   
  7.   
  8.     using std::string;   
  9.     using std::vector;   
  10.     using std::list;   
  11.   
  12.     class Disk_Routine   
  13.     {   
  14.     public:   
  15.         Disk_Routine(unsigned int FAT_size):FAT(FAT_size){}   
  16.         void write(string file_name,unsigned int file_size);   
  17.         void rwirte(string file_name,unsigned int file_size);   
  18.         void del(string file_name);   
  19.         void disp_FAT();   
  20.         void disp_Dir_Table();   
  21.            
  22.     private:   
  23.         unsigned int get_Avai_Sector_Num();   
  24.         vector<int> FAT;   
  25.         list<Dir_Entry> dir_entry_table;   
  26.         static const unsigned int SECTOR_SIZE;   
  27.         static const unsigned int FILE_NAME_MAX_SIZE;   
  28.     };   
  29. #endif   

Disk_Routine.cpp

Code:
  1. #include "Disk_Routine.h"   
  2. #include <iostream>   
  3. #include <iomanip.h>   
  4.   
  5. using std::vector;   
  6. using std::list;   
  7. using std::string;   
  8. using std::cout;   
  9. using std::cerr;   
  10. using std::endl;   
  11.   
  12. const unsigned int Disk_Routine::SECTOR_SIZE = 1024;   
  13. const unsigned int Disk_Routine::FILE_NAME_MAX_SIZE = 8;   
  14.   
  15. void Disk_Routine::write(string file_name,unsigned int file_size)   
  16. {   
  17.     if(file_name.size() > FILE_NAME_MAX_SIZE)   
  18.     {   
  19.         cerr<<"the file name is too long,failed"<<endl;   
  20.         return;   
  21.     }   
  22.        
  23.     unsigned int request_sector_num;   
  24.        
  25.     if( file_size % SECTOR_SIZE == 0)   
  26.     {   
  27.         request_sector_num = file_size / SECTOR_SIZE;   
  28.     }   
  29.     else  
  30.     {   
  31.         request_sector_num = file_size / SECTOR_SIZE + 1;   
  32.     }   
  33.        
  34.     if(request_sector_num > get_Avai_Sector_Num())   
  35.     {   
  36.         cerr<<"the file to long to storage in the disk,failed"<<endl;   
  37.         return;   
  38.     }   
  39.        
  40.     list<Dir_Entry>::iterator det_it = dir_entry_table.begin();   
  41.     for(;det_it != dir_entry_table.end();det_it++)   
  42.     {   
  43.         if(det_it->get_File_Name() == file_name)   
  44.         {   
  45.             cerr<<"the file is already existed,failed"<<endl;   
  46.             return;   
  47.         }   
  48.     }   
  49.        
  50.     vector<int>::iterator fat_it = FAT.begin();   
  51.     vector<int>::iterator loc_it;   
  52.     unsigned int index = 0;   
  53.     for(;fat_it != FAT.end();fat_it++,index++)   
  54.     {   
  55.         if(*fat_it == 0)   
  56.         {   
  57.             loc_it = fat_it;   
  58.             break;   
  59.         }   
  60.     }   
  61.        
  62.     dir_entry_table.push_back(Dir_Entry(file_name,index,request_sector_num));   
  63.        
  64.     fat_it = loc_it + 1;   
  65.     index++;   
  66.     for(;(request_sector_num != 0) && (fat_it != FAT.end());fat_it++,index++)   
  67.     {   
  68.         if(*fat_it == 0)   
  69.         {   
  70.             request_sector_num--;   
  71.             *loc_it = index;    
  72.             if(request_sector_num != 0)   
  73.             {   
  74.                 loc_it = fat_it;   
  75.             }   
  76.         }   
  77.     }   
  78.     *loc_it = -1;   
  79.     cout<<"CREATE SUCCESS"<<endl;   
  80. }   
  81.   
  82. void Disk_Routine::rwirte(string file_name,unsigned int file_size)   
  83. {   
  84.     if(file_name.size() > FILE_NAME_MAX_SIZE)   
  85.     {   
  86.         cerr<<"the file name is too long,failed"<<endl;   
  87.         return;   
  88.     }   
  89.        
  90.     list<Dir_Entry>::iterator det_it = dir_entry_table.begin();   
  91.        
  92.     for(;det_it != dir_entry_table.end();det_it++)   
  93.     {   
  94.         if(det_it->get_File_Name() == file_name)   
  95.         {   
  96.             break;   
  97.         }   
  98.     }   
  99.        
  100.     if(det_it == dir_entry_table.end())   
  101.     {   
  102.         cerr<<"the file doesn't exist"<<endl;   
  103.         return;   
  104.     }   
  105.        
  106.     unsigned int request_sector_num;   
  107.        
  108.     if(file_size % SECTOR_SIZE == 0)   
  109.     {   
  110.         request_sector_num = file_size / SECTOR_SIZE;   
  111.     }   
  112.     else  
  113.     {   
  114.         request_sector_num = file_size / SECTOR_SIZE + 1;   
  115.     }   
  116.        
  117.     vector<int>::iterator fat_it;   
  118.     unsigned int ori_sector_num = det_it->get_Sector_Num();   
  119.     unsigned int i,diff;   
  120.     int tmp,cur_index,fat_index;   
  121.        
  122.     if(request_sector_num > get_Avai_Sector_Num() - det_it->get_Sector_Num())   
  123.     {   
  124.         cerr<<"the file to long to storage in the disk,failed"<<endl;   
  125.         return;   
  126.     }   
  127.     else if(request_sector_num < ori_sector_num)   
  128.     {   
  129.         det_it->set_Sector_Num(request_sector_num);   
  130.         cur_index = det_it->get_First_Sector();   
  131.         for(i = 1;i <= ori_sector_num;i++)   
  132.         {   
  133.             if(i < request_sector_num)   
  134.             {   
  135.                 cur_index = FAT.at(cur_index);   
  136.             }   
  137.             else if(i == request_sector_num)   
  138.             {   
  139.                 tmp = FAT.at(cur_index);   
  140.                 FAT.at(cur_index) = -1;   
  141.                 cur_index = tmp;   
  142.             }   
  143.             else  
  144.             {   
  145.                 tmp = FAT.at(cur_index);   
  146.                 FAT.at(cur_index) = 0;   
  147.                 cur_index = tmp;   
  148.             }   
  149.         }   
  150.     }   
  151.     else if(request_sector_num > ori_sector_num)   
  152.     {   
  153.         diff = request_sector_num - ori_sector_num;   
  154.         det_it->set_Sector_Num(request_sector_num);   
  155.         cur_index = det_it->get_First_Sector();   
  156.         for(i = 1;i <= ori_sector_num;i++)   
  157.         {   
  158.             if(i == ori_sector_num)   
  159.             {   
  160.                 for(fat_it = FAT.begin(),fat_index = 0;fat_it != FAT.end();fat_it++,fat_index++)   
  161.                 {   
  162.                     if(*fat_it == 0)   
  163.                     {   
  164.                         if(!(diff--))   
  165.                         {   
  166.                             break;   
  167.                         }      
  168.                         FAT.at(cur_index) = fat_index;   
  169.                         cur_index = fat_index;   
  170.                     }   
  171.                 }   
  172.                    
  173.                 FAT.at(cur_index) = -1;   
  174.             }   
  175.             else  
  176.             {   
  177.                 cur_index = FAT.at(cur_index);   
  178.             }   
  179.         }   
  180.     }   
  181.     else  
  182.     {   
  183.         cout<<"THE FILE SIZE IS THE SAME AS BEFORE";   
  184.         return;   
  185.     }   
  186.        
  187.     cout<<"RECREATE SUCCESS"<<endl;   
  188. }   
  189.   
  190. void Disk_Routine::del(string file_name)   
  191. {   
  192.     list<Dir_Entry>::iterator det_it = dir_entry_table.begin();   
  193.     for(;det_it != dir_entry_table.end();det_it++)   
  194.     {   
  195.         if(det_it->get_File_Name() == file_name)   
  196.         {   
  197.             break;   
  198.         }   
  199.     }   
  200.        
  201.     if(det_it == dir_entry_table.end())   
  202.     {   
  203.         cerr<<"the file doesn't exist"<<endl;   
  204.         return;   
  205.     }   
  206.        
  207.     unsigned int cur_sector;   
  208.     unsigned int next_sector;   
  209.     unsigned int sector_num = det_it->get_Sector_Num();   
  210.        
  211.     for(cur_sector = det_it->get_First_Sector();sector_num != 0;sector_num--)   
  212.     {   
  213.         next_sector = FAT.at(cur_sector);   
  214.         FAT.at(cur_sector) = 0;   
  215.         cur_sector = next_sector;   
  216.     }   
  217.        
  218.     dir_entry_table.erase(det_it);   
  219.     cout<<"DELETE SUCCESS"<<endl;   
  220. }   
  221.   
  222. void Disk_Routine::disp_FAT()    
  223. {   
  224.     cout<<"------------------FAT-------------------"<<endl;   
  225.     vector<int>::iterator fat_it = FAT.begin();   
  226.     unsigned int index = 0;   
  227.        
  228.     for(;fat_it != FAT.end();fat_it++,index++)   
  229.     {   
  230.         cout<<"sector_no:"<<right<<setw(3)<<index;   
  231.         cout<<"          "<<"next_sector:"<<setw(3)<<*fat_it<<endl;   
  232.     }   
  233.     cout<<"---------------End of FAT---------------"<<endl;   
  234. }   
  235.   
  236. void Disk_Routine::disp_Dir_Table()    
  237. {   
  238.     cout<<"---------------File List----------------"<<endl;   
  239.     list<Dir_Entry>::iterator det_it = dir_entry_table.begin();   
  240.     unsigned index = 1;   
  241.        
  242.     if(det_it == dir_entry_table.end())   
  243.     {   
  244.         cout<<"NO FILE"<<endl;   
  245.     }   
  246.     else  
  247.     {   
  248.         for(;det_it != dir_entry_table.end();index++)   
  249.         {   
  250.             cout<<"FILE "<<index<<endl;   
  251.             cout<<left<<setw(15)<<"file name:"<<setw(FILE_NAME_MAX_SIZE)<<det_it->get_File_Name()<<endl;;   
  252.             cout<<setw(15)<<"first sector:"<<setw(3)<<det_it->get_First_Sector()<<endl;   
  253.             cout<<setw(15)<<"sector number:"<<setw(3)<<det_it->get_Sector_Num()<<endl;   
  254.            
  255.             if((++det_it) != dir_entry_table.end())   
  256.             {   
  257.                 cout<<"****************************************"<<endl;   
  258.             }   
  259.         }   
  260.     }   
  261.     cout<<"****************************************"<<endl;   
  262.     cout<<setw(21)<<left<<"disk available space:"<<get_Avai_Sector_Num() * SECTOR_SIZE<<" bytes"<<endl;   
  263.     cout<<setw(21)<<"disk total space:"<<FAT.size() * SECTOR_SIZE<<" bytes"<<endl;   
  264.     cout<<"------------End of File List------------"<<endl;   
  265. }   
  266.   
  267. unsigned int Disk_Routine::get_Avai_Sector_Num()   
  268. {   
  269.     unsigned int avai_sector_num = 0;   
  270.     vector<int>::iterator fat_it = FAT.begin();   
  271.     for(;fat_it != FAT.end();fat_it++)   
  272.     {   
  273.         if(*fat_it == 0)   
  274.         {   
  275.             avai_sector_num++;   
  276.         }   
  277.     }   
  278.     return avai_sector_num;   
  279. }   
  280.   

main.cpp

Code:
  1. #include <iostream>   
  2. #include <string>   
  3. #include <limits>    
  4. #include "Disk_Routine.h"   
  5.   
  6. using std::string;   
  7. using std::cerr;   
  8. using std::cout;   
  9. using std::cin;   
  10. using std::endl;   
  11. using std::numeric_limits;   
  12. using std::streamsize;   
  13.   
  14. int main()   
  15. {   
  16.     Disk_Routine dr(20);   
  17.     char c;   
  18.     bool flag = true;   
  19.     string file_name;   
  20.     unsigned int file_size;   
  21.        
  22.     cout<<"OS BIG WORK NO 4 BY MARCUSXING 2009 12 9"<<endl;   
  23.     cout<<"****************************************"<<endl;   
  24.     cout<<"please select a number to do something"<<endl;   
  25.     cout<<"h:help message"<<endl;  
  26.     cout<<"q:quit"<<endl;  
  27.     cout<<"1:create a file"<<endl;   
  28.     cout<<"2:recreate a exist file"<<endl;   
  29.     cout<<"3:delete a file"<<endl;   
  30.     cout<<"4:display the FAT"<<endl;   
  31.     cout<<"5:display the File List"<<endl;      
  32.        
  33.     while(flag)   
  34.     {   
  35.         cout<<"please enter your choice:";   
  36.         if(!cin)   
  37.         {   
  38.             cin.ignore(numeric_limits<streamsize>::max(),'/n');   
  39.         }   
  40.         cin>>c;   
  41.            
  42.         switch(c)   
  43.         {   
  44.         case '1':   
  45.         case '2':   
  46.             cin.ignore(numeric_limits<streamsize>::max(),'/n');   
  47.             cout<<"please enter the file name:";   
  48.             cin>>file_name;   
  49.             cin.ignore(numeric_limits<streamsize>::max(),'/n');   
  50.             cout<<"please enter the file size(unit:byte):";   
  51.                
  52.             if(!(cin>>file_size))   
  53.             {   
  54.                 cerr<<"your input has something wrong"<<endl;   
  55.                 flag = false;   
  56.                 break;   
  57.             }   
  58.                
  59.             if(static_cast<int>(file_size) <= 0)   
  60.             {   
  61.                 cerr<<"file size must be a positive number"<<endl;   
  62.                 break;   
  63.             }   
  64.                
  65.             if(c == '1')   
  66.             {   
  67.                 dr.write(file_name,file_size);   
  68.             }   
  69.             else if(c == '2')   
  70.             {   
  71.                 dr.rwirte(file_name,file_size);   
  72.             }   
  73.             cin.ignore(numeric_limits<streamsize>::max(),'/n');   
  74.             break;   
  75.         case '3':   
  76.             cin.ignore(numeric_limits<streamsize>::max(),'/n');   
  77.             cout<<"please enter the file name:";   
  78.             cin>>file_name;   
  79.             dr.del(file_name);   
  80.             cin.ignore(numeric_limits<streamsize>::max(),'/n');   
  81.             break;   
  82.         case '4':   
  83.             cin.ignore(numeric_limits<streamsize>::max(),'/n');   
  84.             dr.disp_FAT();   
  85.             break;   
  86.         case '5':   
  87.             cin.ignore(numeric_limits<streamsize>::max(),'/n');   
  88.             dr.disp_Dir_Table();   
  89.             break;   
  90.         case 'q':   
  91.             flag = false;   
  92.             break;   
  93.         case 'h':   
  94.             cin.ignore(numeric_limits<streamsize>::max(),'/n');   
  95.             cout<<"h:help message"<<endl;  
  96.             cout<<"q:quit"<<endl;  
  97.             cout<<"1:create a file"<<endl;   
  98.             cout<<"2:recreate a exist file"<<endl;   
  99.             cout<<"3:delete a file"<<endl;   
  100.             cout<<"4:display the FAT"<<endl;   
  101.             cout<<"5:display the File List"<<endl;       
  102.             break;   
  103.         default:   
  104.             cout<<"are you kidding me?"<<endl;   
  105.             return -1;   
  106.             break;   
  107.         }   
  108.     }   
  109.   
  110.     return 0;   
  111. }   

 

抱歉!评论已关闭.