C/C++模拟操作系统文件操作
来源:互联网 发布:开票软件怎么用 编辑:程序博客网 时间:2024/06/16 22:01
效果图
基本要求
利用磁盘文件实现操作系统的文件管理功能,主要包括目录结构的管理、外存空间的分配与释放以及空闲空间管理三部分。
实验提示
- 通过初始化操作建立一个模拟外存空间的虚拟磁盘文件,在该文件中保存目录和文件内容。创建该文件时应创建初始的根目录内容、文件分配表。根目录实为一特殊文件,其开始内容为空,大小为一个块。
- 文件目录项(可以采用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 7using 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(); in.read(c, 2*length); in.close(); } void write_fat(char *c) { FILE *fp = fopen(format_file_name.c_str(), "rb+"); if(fp == NULL) return; fwrite( c, 2*get_block_count(), 1, fp); fclose(fp); } void read_block(int block_no, char *str) { ifstream in (format_file_name.c_str(), ios::in|ios::binary); if(!in.is_open()) { alert("Failed to create file!!"); return; } in.seekg((get_block_count()*2 + block_no*BLOCK_SIZE),ios::beg); in.read(str, BLOCK_SIZE); in.close(); } void write_block(int block_no, char *str) { FILE *fp = fopen(format_file_name.c_str(), "rb+"); if(fp == NULL) { return; } int i = get_block_count()*2 + block_no*BLOCK_SIZE; fseek(fp, i, 0); fwrite(str, BLOCK_SIZE,1,fp); fclose(fp); } int get_empty_block_num(int start) {//start开始以后后面第一个空闲块号 char *fat; unsigned short *tmp; int blockNum = -1; int i, length; length = get_block_count(); fat = new char [get_block_count()*2]; read_fat(fat); tmp = (unsigned short*)fat; for(i = 0; i < start; i++, tmp++); for(; i < length; i++, tmp++) { //cout<<(short *)*tmp<<endl; if( *tmp == EMPTY_BLOCK) { blockNum = i; break; } } delete[] fat; //cout<<blockNum<<endl; return blockNum; } void set_fat_item(int idx, unsigned short c) {//设置FAT表第idx项为c char *fat, *tmp; unsigned short *shortPnt; fat = new char [get_block_count()*2]; read_fat(fat); shortPnt=(unsigned short*)fat; *(shortPnt+idx) = c; //printf("%4x%d",c,idx); write_fat(fat); delete[] fat; } char get_fat_item(int idx) { char *fat, *tmp; fat = new char [get_block_count()*2]; read_fat(fat); char c = *(fat+idx); delete[] fat; return c; } bool is_valid_name (string &str) {//判断文件名是否符合规矩 if(str.find("\\", 0) != -1) { alert("The file or directory name includes illegal characters"); return false; }else if(str.length() > 8) { alert("The file or directory name can not exceed 8 characters"); return false; }else if(str == "." || str == "..") { alert("The file or directory name can not make '.' Or '..'"); return false; } return true; } void display_vd_content(int pos, int length) {//显示内容核心 ifstream in(format_file_name.c_str(), ios::binary|ios::in); if(!in.is_open()) { alert("Failed to open file!!"); return; } in.seekg(pos, ios::beg); int i = 0; char c; while(i < length) { printf("%08d ", pos+i); for(int j = 0; j < 16; j++) { char tmp[20]; in.read(&c, 1); if(in.eof()) { break; } sprintf(tmp, "%02x", c); if(strlen(tmp) > 2) { string tmm = tmp; cout<<tmm.substr(strlen(tmp)-2, 2)<<" "; }else { printf("%02x ",c); } i++; } in.seekg(-16, ios::cur); cout<<" "; for(int j = 0; j < 16; j++) { in.read(&c, 1); if(in.eof()) { break; } if(c > 13 && c < 127) { cout<<c; }else { cout<<"."; } } cout<<endl; } in.close(); } void display_content(string &str1, string &str2) {//显示内容 int start = to_integer(str1); if(start >= 0) { int length = to_integer(str2); if(length > 0) { display_vd_content(start, length); }else { display_vd_content(start, 256); } }else { } } void display_content(string &str1) { toLowerCase(str1); if(str1 == "fat") { ifstream in (format_file_name.c_str(), ios::in|ios::binary|ios::ate); long size = in.tellg(); in.close(); display_vd_content(0, (size/(BLOCK_SIZE+2))*2 ); } } void write_directory_content(int block_no, int parent_block_no, char *dateTime) { char *directory_content = new char[BLOCK_SIZE]; memset(directory_content, 0, BLOCK_SIZE); FCB *tmp = (FCB *)directory_content; strcpy(tmp->name , "."); strcpy(tmp->dateTime, dateTime); tmp->size = BLOCK_SIZE; tmp->first_block = block_no; tmp->type = 2; tmp++; strcpy(tmp->name , ".."); strcpy(tmp->dateTime, dateTime); tmp->size = BLOCK_SIZE; tmp->first_block = parent_block_no; tmp->type = 2; tmp++; write_block(block_no, directory_content); delete []directory_content; } void do_format(string &str, int integer, int Bsize) {//创建FAT表文件 if(!is_power_of_two(integer)) { alert("Not the power of 2"); } else if (integer > 65535) {//64K minus FAT minus 0000 alert("Exceeds the maximum memory range"); } else { ofstream out(str.c_str(), ios::out|ios::binary); if(!out.is_open()) { alert("Failed to create file!!"); } else { format_file_name = str; cout<<"Formatting: "<<str<<", BlockSize: "<<Bsize<<", BlockNum: "<<integer<<endl; int myByte = LAST_BLOCK; out.write((char*)&myByte, 2); myByte = EMPTY_BLOCK; for(int i = 0; i < integer-1; i++) { out.write((char*)&myByte, 2); } char buf[BLOCK_SIZE]; memset(buf, 0, BLOCK_SIZE); for(int i = 0; i < integer; i++) { out.write(buf, BLOCK_SIZE); } char dateTime[15]; setDateTime(dateTime); write_directory_content(0,0,dateTime); out.close(); } } } void format(){ string aa = "a"; do_format(aa, 32, BLOCK_SIZE); } void help() { } FCB* get_directory_item(FCB *content, int type, char *name) { FCB *tmp = content; for(int i = 0; i < BLOCK_SIZE/sizeof(FCB); i++, tmp++) { if(tmp->type == type) { if(strcmp(tmp->name, name)==0) { return tmp; } } } return NULL; } void md(char *name) {//创建目录 string ss = name; if(!is_valid_name(ss)) { return; } FCB *directory_content = new FCB[BLOCK_SIZE]; read_block(current_directory_block_no, (char *)directory_content); if(get_directory_item(directory_content, 1, name) != NULL || get_directory_item(directory_content, 2, name) != NULL) { alert("Directory name is occupied"); delete[] directory_content; return; } int block_no = get_empty_block_num(0); if(block_no < 0) { alert("insufficient space in drive"); delete[] directory_content; return; } FCB *tmp = directory_content; for(int i = 0; i < BLOCK_SIZE/sizeof(FCB); i++, tmp++) { if(tmp->type == 0) { char dateTime[15]; setDateTime(dateTime); strcpy(tmp->name, name); tmp->size = BLOCK_SIZE; tmp->first_block = block_no; strcpy(tmp->dateTime, dateTime); tmp->type=(char)2; write_block(current_directory_block_no, (char *)directory_content); set_fat_item(block_no, LAST_BLOCK); delete[] directory_content; write_directory_content(block_no, current_directory_block_no, dateTime); return; } } } void rd(string &name) {//删除目录 char aa[100]; strcpy(aa, name.c_str()); if(!is_valid_name(name)) { return; } FCB *directory_content = new FCB[BLOCK_SIZE]; read_block(0, (char *)directory_content); FCB *tmp, *tmp2; tmp = directory_content; tmp2 = get_directory_item(directory_content, 2, aa); if(tmp2 != NULL) { char *content = new char [BLOCK_SIZE]; memset(content, 0, BLOCK_SIZE); int block_no = tmp2->first_block; cout<<block_no<<endl; write_block(block_no, content); set_fat_item(block_no, EMPTY_BLOCK); memset((char *)tmp2, 0, sizeof(FCB)); write_block(0, (char *)directory_content); delete[] directory_content; }else { cout<<"Not Find Name"<<endl; } } void dir() {//显示目录 FCB *directory_content = new FCB [BLOCK_SIZE]; read_block(current_directory_block_no, (char *)directory_content); FCB *tmp = directory_content; for(int i = 0; i < BLOCK_SIZE/sizeof(FCB); i++, tmp++) { if(tmp->type == 1 || tmp->type == 2) { int type = tmp->type; if(tmp->first_block >=0 ) { printf("%d\t", tmp->first_block); }else { printf("\t"); } *(tmp->dateTime+15) = 0; printf("%s\t", tmp->dateTime); if(type == 2) { printf("<DIR>\t"); }else { printf("%d\t", tmp->size); } printf("%s\n", tmp->name); } } delete []directory_content; } void cd(string &name) {//定位 if(name == "NULL") { if(current_directory.length() == 0) { cout<<"\\ "<<endl; }else { cout<<current_directory<<endl; } }else if(name == ".") { return; }else if(name == "\\"){ current_directory_block_no = 0; current_directory = ""; return; }else { FCB *directory_content = new FCB [BLOCK_SIZE]; read_block(current_directory_block_no, (char *)directory_content); char name1[100]; strcpy(name1, name.c_str()); FCB *tmp = get_directory_item(directory_content, 2, name1); if(tmp == NULL) { alert("Not Find Contents"); }else { current_directory_block_no = tmp->first_block; current_directory+="\\"; current_directory+=name1; } delete []directory_content; } } void mk(char *name, int size, char *content) {//创建文件 string ss = name; if(!is_valid_name(ss)) { return; } FCB *directory_content = new FCB[BLOCK_SIZE]; read_block(current_directory_block_no, (char *)directory_content); if(get_directory_item(directory_content, 1, name) != NULL || get_directory_item(directory_content, 2, name) != NULL) { alert("Directory name is occupied"); delete[] directory_content; return; } int block_no = get_empty_block_num(0); if(block_no < 0) { alert("insufficient space in drive"); delete[] directory_content; return; } FCB *tmp = directory_content; for(int i = 0; i < BLOCK_SIZE/sizeof(FCB); i++, tmp++) { if(tmp->type == 0) { char dateTime[15]; setDateTime(dateTime); strcpy(tmp->name, name); strcpy(tmp->dateTime, dateTime); tmp->type=(char)1; tmp->size = size; if(size > 0) { tmp->first_block = block_no; int block_count = (int)ceil(size/(double)BLOCK_SIZE); int *block_numbers = new int[sizeof(int)*block_count]; *block_numbers = block_no; for(int j = 1; j < block_count; j++) { *(block_numbers+j) = get_empty_block_num(*(block_numbers + j - 1) + 1); if(*(block_numbers + j) == -1) { alert("There is not enough memory space"); delete[] block_numbers; delete[] directory_content; return; } } for(int j = 0; j < block_count; j++) { if( (j+1) == block_count) { set_fat_item(*(block_numbers + j), LAST_BLOCK); }else { set_fat_item(*(block_numbers + j), *(block_numbers + j + 1)); } write_block(*(block_numbers+j), (char *)(content+BLOCK_SIZE*j)); } delete[] block_numbers; }else { tmp->first_block = -1; } write_block(current_directory_block_no, (char *)directory_content); delete[] directory_content; return; } } alert("The parent directory is full"); delete[] directory_content; } void del(string &name) {//删除文件 } void put(string &src, string &dest) { FILE *fp = fopen(src.c_str(), "rb"); if(fp == NULL) { alert("Did not find the local file"); }else { int size = get_file_size(src); char *content = new char [(int)(ceil(size/(double)BLOCK_SIZE)) * BLOCK_SIZE]; memset(content, 0, ceil(size/(double)BLOCK_SIZE) * BLOCK_SIZE); fread(content, size, 1, fp); if(dest == "NULL") { char aa[100]; strcpy(aa, src.c_str()); mk(aa, size, content); }else { char bb[100]; strcpy(bb, dest.c_str()); mk(bb, size, content); } delete[] content; } fclose(fp); }}#endif // DOS_H_INCLUDED
主函数文件
#include <iostream>#include <string>#include <cstdlib>#include <ctime>#include "windows.h"#include "FCB.h"#include "DOS.h"//char current_directory[256] = "";//当前目录//char format_file_name[32];//虚拟磁盘文件名using namespace std;using namespace DOS;int main(){ /*char *content = new char [sizeof(FCB)]; memset(content, 0, sizeof(FCB)); cout<<content<<endl; return 0;*/ while(1) { string cmd, str[10]; int length; if(current_directory.length() == 0) { cout<<"\\$ "; }else { cout<<current_directory<<"$ "; } getline(cin,cmd); length = split(cmd, str, ' '); toLowerCase(str[0]); if(str[0] == "exit") { exit(0); } else if(str[0] == "cls") { system("cls"); } else if(str[0] == "help" || str[0] == "?") { help(); } else if(str[0] == "format") { if(length == 3) { do_format(str[1], to_integer(str[2]), BLOCK_SIZE); }else { format(); } } else if(str[0] == "info") { if(length == 2) { display_content(str[1]); }else if (length == 3) { display_content(str[1], str[2]); }else { alert("Error command!"); } } else if(str[0] == "md" && length == 2) { char aa[100]; strcpy(aa, str[1].c_str()); md(aa); } else if(str[0] == "dir") { dir(); } else if(str[0] == "cd"){ //char bb[100]; //strcpy(bb, str[1].c_str()); if(length == 2) { cd(str[1]); }else { string bb = "NULL"; cd(bb); } } else if(str[0] == "mk" && length == 2){ char bb[100]; strcpy(bb, str[1].c_str()); mk(bb, 0, NULL); } else if(str[0] == "mk" && length == 3){ int size = to_integer(str[2]); if(size > 0) { char *content = (char *)malloc(size); memset(content, 0, size); char cc[100]; strcpy(cc, str[1].c_str()); mk(cc, size, content); } } else if(str[0] == "put" && length == 2){ string cc = "NULL"; put(str[1], cc); } else if(str[0] == "put" && length == 3){ put(str[1], str[2]); } else if(str[0] == "rd" && length == 2){ rd(str[1]); } else if(str[0] == "del" && length == 2){ } else { alert("Error command!"); } } return 0;}
1 0
- C/C++模拟操作系统文件操作
- linux操作系统下c语言编程入门 -- (3)文件操作
- linux操作系统下c语言编程入门--文件操作
- [C/C++]文件操作
- 操作系统实验--C语言模拟进程管理
- 【操作系统】C语言模拟操作系统优先数调度算法
- 【操作系统】C语言模拟操作系统实现动态分区分配算法
- 操作系统—C语言进程调度模拟.c
- 操作系统-C语言模拟固定分区储存.c
- 简单的文件系统模拟C/C++(操作系统)
- C/C++/Window 文件操作
- 【C/C++】C++文件操作
- Windows文件操作【C/C++】
- 【C/C++】文件流操作
- c文件操作
- C文件操作
- C的文件操作
- c语言文件操作
- 判断ImageView当前的图片是哪个图片,然后根据当前图片来做一些操作
- 关于tcp网络通讯的几个场景的小测试
- 机器学习笔记——第2篇
- poj1915之BFS
- 高仿CSDN编写文章,发表文章的工具
- C/C++模拟操作系统文件操作
- UVA
- bootstrap-table.js多种方法填充单元格数据
- 机器学习笔记——第3篇
- LeetCode算法题——27. Remove Element
- MySQL使用规范备注
- 虚拟机内elasticsearch集群的详细安装过程
- 自定义压缩解压
- TSP_旅行商问题