效果图
基本要求
利用磁盘文件实现操作系统的文件管理功能,主要包括目录结构的管理、外存空间的分配与释放以及空闲空间管理三部分。
实验提示
- 通过初始化操作建立一个模拟外存空间的虚拟磁盘文件,在该文件中保存目录和文件内容。创建该文件时应创建初始的根目录内容、文件分配表。根目录实为一特殊文件,其开始内容为空,大小为一个块。
- 文件目录项(可以采用FCB格式)应包括类型(目录 or文件)、创建日期、大小、第一个磁盘块块号。
- 显示命令提示符“$”,并根据输入命令完成相应的文件操作:
- MD(创建子目录):创建目录文件,并在父目录文件中增加目录项。
- CD(切换工作目录):根据当前目录切换到指定目录。
- RD(删除子目录):搜索所要删除的目录是否为空目录,若是则删除。
- MK(创建空文件):创建指定大小的文件(如输入命令 “mk test 2000”,表示创建大小为2000字节的test文件),并在父目录中添加文件名称;还应对FAT表进行适当修改。
- DIR:列出当前目录的所有目录项。
- FORMAT:根据进一步的虚拟磁盘文件名和块个数信息创建出虚拟磁盘文件。
代码
首先是基本DOS命令函数头文件.< < DOS.h > >
#ifndef DOS_H_INCLUDED
#define DOS_H_INCLUDED
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include <ctime>
#include <cstdlib>
#include <cmath>
#define LAST_BLOCK 0xFFFF//fat16
#define EMPTY_BLOCK 0x0000
#define BLOCK_SIZE 1024
#define BEEP 7
using namespace std;
typedef struct FCB{
char name[8];//文件或者目录名
int size;//文件或者目录字节数
int first_block;//第一个块号
char dateTime[15];//日期时间
char type;//1.文件 2.目录 0.空闲
}FCB;
string current_directory = "";
string format_file_name = "";
int current_directory_block_no = 0;//当前目录块号
namespace DOS {
void alert(char str[]) {
cout<<str<<endl;
}
bool is_all_digits(string &str) {
//判断是否为全数字
for(int i = 0; i < str.length(); i++) {
if(str[i] < '0' || str[i] > '9') {
return false;
}
}
return true;
}
int to_integer (string &str) {
//字符串转化为数字
if(is_all_digits(str)) {
return atoi(str.c_str());
}
return -1;
}
bool is_power_of_two(int i) {
//判断是否为2的整数次幂
if(i % 2 != 0) {
return false;
} else {
while(i != 1) {
if(i%2 != 0) {
return false;
}
i = i/2;
}
}
return true;
}
void trim (char *str) {
//去掉前后空格
char *p = str;
while(*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
p++;
}
strcmp(str, p);
int i = strlen(str)-1;
while(str[i] == ' ' || str[i] == '\t' || str[i] == '\r' || str[i] == '\n') {
i--;
}
str[i+1] = '\0';
}
void toUpperCase (string &str) {
transform(str.begin(), str.end(), str.begin(), ::toupper);
}
void toLowerCase (string &str) {
transform(str.begin(), str.end(), str.begin(), ::tolower);
}
int split (string &str,string ss[10],char ch) {
//分割字符串
int i = 0, j = 0, k = 0;
while(str[i] == ch) {
i++;
}
// if(str[i] == 0) {
// return 0;
// }
char a[10][40];
int index = 0;
for(;i < str.length(); i++) {
if(str[i] != ch) {
a[j][k++] = str[i];
}else {
a[j][k] = '\0';
if(k != 0) {
ss[index] = a[j];
index++;
}
j++;
k = 0;
}
}
a[j][k] = '\0';
if(k != 0) {
ss[index] = a[j];
index++;
}
return index;
}
void setDateTime(char dateTime[]) {
time_t ticks = time(NULL);
struct tm *t = localtime(&ticks);
strftime(dateTime, 16, "%Y%m%d %H%M%S", t);
}
int get_block_count() {
//获取块大小
ifstream in (format_file_name.c_str(), ios::in|ios::binary|ios::ate);
long size = in.tellg();
in.close();
return size/(BLOCK_SIZE+2);
}
int get_file_size(string &str) {
//获取文件大小
ifstream in (str.c_str(), ios::in|ios::binary|ios::ate);
long size = in.tellg();
in.close();
return size;
}
void read_fat(char *c) {
ifstream in (format_file_name.c_str(), ios::in|ios::binary);
if(!in.is_open()) {
alert("Failed to create file!!");
return;
}
int length = get_block_count();