This is my operating system class design.
scanner.h
#include<string> using namespace std; #pragma once struct Scanner { int si; ]; Scanner(char ss[]){ int i; ; ss[i]; i++)s[i] = ss[i]; s[i] = ; si = ; while (s[si] == ' ')si++; } bool hasNext(){ ; } string next(){ string ans = ""; while (s[si] != ' '&&s[si])ans += s[si++]; while (s[si] == ' ')si++; return ans; } };
path.h
#include"disk.h" #include<string> #include<string.h> using namespace std; #pragma once struct Path{ Item a[]; int ai; Path(){ ai = ; a[].block = ; a[].isFile = false; strcpy(a[].name, "root"); } void push(Item it){ a[ai++] = it; } Item pop(){ ){ Item it; it.block = -; return it; } return a[--ai]; } Item peek(){ ]; } string gets(){ string s = ""; extern string str(char*); ; i < ai; i++){ s +=string(a[i].name)+"\\"; } return s; } void home(){ ai = ; } };
disk.h
#pragma once //组长块 struct Leader{ short blockCnt; short nextLeader; ]; }; struct Dir { short blockCnt; short itemCnt; ]; }; struct Item{ ]; short block; bool isFile; ]; }; struct Block{ ]; };
main.cpp
#include<iostream> #include<math.h> #include<string> #include<string.h> #include"scanner.h" #include"disk.h" #include"path.h" using namespace std; const char disk[] = "disk.txt"; ; ; ; ; ; Leader super; string replace(string src, string olds, string news){ string ans = ""; ; i < src.length();){ int j; ; j < olds.length() && i + j < src.length(); j++){ if (src[j + i] != olds[j]){ break; } } if (j == olds.length()){ ans += news; i += j; } else{ ans += src[i]; i++; } } return ans; } void readBlock(short x, void *block){ FILE*file = fopen(disk, "rb"); fseek(file, x*BlockCapacity, ); fread(block, , file); fclose(file); } void writeBlock(short x, void* block){ FILE *file = fopen(disk, "rb+"); fseek(file, x*BlockCapacity, ); fwrite(block, , file); fclose(file); } Item getItem(]){ Dir dir; readBlock(folder, &dir); Item it; it.block = -; ; ; i < dir.blockCnt; i++){ Item a[]; readBlock(dir.data[i], a); ; j < && k++ < dir.itemCnt; j++){ ){ it = a[j]; return it; } } } return it; } ]){ Item it = getItem(x, name); )return false; else return true; } void format(){ //删除旧磁盘,创建新磁盘,设置新磁盘长度 remove(disk); FILE*file = fopen(disk, "w");//write会覆盖,没有文件就创建文件 fseek(file, BlockCapacity*BlockCount - , ); char c = 'a'; fwrite(&c, , , file); fclose(file); //第0块 ] = "root"; ] = "haha"; Block b0; strcpy(b0.a, userName); strcpy(b0.a + , password); b0.a[] = ;//0个用户 writeBlock(, &b0); //初始化所有组长块 int leader = BlockCount - BlocksPerGroup; ; leader -= BlocksPerGroup){ Leader l; l.blockCnt = BlocksPerGroup - ; l.nextLeader = leader + BlocksPerGroup; ; i < l.blockCnt; i++){ l.member[i] = i + + leader; } writeBlock(leader, &l); } //初始化超级块 leader += BlocksPerGroup; Leader super; super.blockCnt = leader - ; super.nextLeader = leader; ; i < super.blockCnt; i++) super.member[i] = + i; writeBlock(, &super); //根目录 Dir root; root.blockCnt = ; root.itemCnt = ; writeBlock(, &root); } int allocBlock(){ ){ int ans = super.nextLeader; ; readBlock(ans, &super); return ans; } else{ return super.member[--super.blockCnt]; } } void freeBlock(short x){ ){ writeBlock(x, &super); super.blockCnt = ; super.nextLeader = x; } else{ super.member[super.blockCnt++] = x; } } void readFile(short x, char s[]){ Dir dir; readBlock(x, &dir); ; ; i < dir.blockCnt; i++){ Block data; readBlock(dir.data[i], &data); ; j < BlockCapacity&&k < dir.itemCnt; j++) s[k++] = data.a[j]; } s[k] = ; } void writeFile(short x, char s[]){ Dir dir; readBlock(x, &dir); + strlen(s); int blockCnt = ceil(1.0*itemCnt / BlockCapacity); if (blockCnt>dir.blockCnt){ for (int i = dir.blockCnt; i < blockCnt; i++){ dir.data[i] = allocBlock(); } } else if (blockCnt < dir.blockCnt){ for (int i = blockCnt; i < dir.blockCnt; i++){ freeBlock(dir.data[i]); } } dir.itemCnt = itemCnt; dir.blockCnt = blockCnt; ; ; i < dir.blockCnt; i++){ Block data; ; j < BlockCapacity&&k < dir.itemCnt; j++) data.a[j] = s[k++]; writeBlock(dir.data[i], &data); } writeBlock(x, &dir); } int addItem(short x, const char *name, bool isFile){ Dir dir; readBlock(x, &dir); if (exist(x, name)){ cout << "此文件夹中已经包含同名文件或文件夹" << endl; ; } ; ){ dir.blockCnt++; dir.data[dir.blockCnt - ] = allocBlock(); } Item t[]; readBlock(dir.data[dir.blockCnt - ], t); strcpy(t[pos].name, name); t[pos].isFile = isFile; t[pos].block = allocBlock(); writeBlock(dir.data[dir.blockCnt - ], t); Dir it; it.blockCnt = ; it.itemCnt = ; writeBlock(t[pos].block, &it); dir.itemCnt++; writeBlock(x, &dir); return t[pos].block; } void deleteFile(short x){ Dir dir; readBlock(x, &dir); ; i < dir.blockCnt; i++){ freeBlock(dir.data[i]); } freeBlock(x); } void deleteFolder(short x){ Dir dir; readBlock(x, &dir); ; ; i < dir.blockCnt; i++){ Item a[]; readBlock(dir.data[i], a); ; j < && k++ < dir.itemCnt; j++){ if (a[j].isFile){ deleteFile(a[j].block); } else { deleteFolder(a[j].block); } } freeBlock(dir.data[i]); } freeBlock(x); } ]){ Dir dir; readBlock(folder, &dir); ; ; i < dir.blockCnt; i++){ Item a[]; readBlock(dir.data[i], a); ; j < && k++ < dir.itemCnt; j++){ ){ if (a[j].isFile){ deleteFile(a[j].block); } else{ deleteFolder(a[j].block); } Item last[]; readBlock(dir.data[dir.blockCnt - ], last); a[j] = last[(dir.itemCnt - ) % ]; writeBlock(dir.data[i], a); == ){ dir.blockCnt--; freeBlock(dir.data[dir.blockCnt]); } dir.itemCnt--; writeBlock(folder, &dir); return; } } } } void start(){ FILE*file = fopen(disk, "r"); ){ cout << "磁盘不存在,将要进行新建磁盘并格式化" << endl; format(); } readBlock(, &super); } void exit(){ writeBlock(, &super); } void debugGroup(){ writeBlock(, &super); ; ; leader < BlockCount&&k++ < ;){ Leader l; readBlock(leader, &l); cout << "leader " << leader << " " << l.blockCnt << ":"; ; i < l.blockCnt; i++){ cout << l.member[i] << " "; } cout << endl; leader = l.nextLeader; } } void ls(short x){ Dir dir; readBlock(x, &dir); ; ; char table[len]; ; i < len; i++)table[i] = '-'; table[len - ] = ; cout << table << endl; ; i < dir.blockCnt; i++){ Item a[]; readBlock(dir.data[i], a); ; j < && k++ < dir.itemCnt; j++){ printf("| %-10s | %-10s |\n", a[j].name, a[j].isFile ? "文件" : "文件夹"); } } cout << table << endl; } int filelen(FILE*file){ fseek(file, , ); return ftell(file); } //a little difficult void tree(short x, const char*name, bool isFile,string prefix, string &treeString){ treeString += prefix + name + "\n"; if (isFile)return; string temp =replace(prefix,"┣", "┃"); temp = replace(temp,"━", " "); temp = replace(temp,"┗", " "); // 一定要注意,一个这个符号是两个空格 Dir dir; readBlock(x, &dir); ; ; i < dir.blockCnt; i++){ Item a[]; readBlock(dir.data[i], a); ; j < && k++ < dir.itemCnt; j++){ if (k == dir.itemCnt) tree(a[j].block,a[j].name,a[j].isFile,temp + "┗━", treeString); else tree(a[j].block, a[j].name,a[j].isFile ,temp + "┣━", treeString); } } } ][] = { "newfile fileName", "创建新文件", "newfolder folderName ", "创建新文件夹", "cd 文件夹名 ", "进入子文件夹", "show 文件名", "显示子文件内容", "ls", "显示当前目录下的全部子项", "tree", "显示以当前目录为根的树形结构", "home ", "返回根目录", "back ", "返回上级目录", "del 文件名或者文件夹名 ", "删除当前目录下的文件或文件夹", "writefile 文件名 文本文件名", "写入文件", "format", "格式化磁盘", "exit", "退出系统", "help", "帮助", "debug", "显示磁盘使用情况", "#" }; void help(){ ]; ; i < ; i++)table[i] = '-'; table[] = ; ; strcmp(cmds[i], ){ )printf("\t\t%s\n", table); printf(]); printf("\t\t%s\n", table); } } void run(){ ]; Path p; cout << "请您一定要注意,退出时要使用exit指令退出,不要关闭控制台" << endl; cout << "因为程序需要用exit()做一些善后工作" << endl; cout << "请使用help命令查看帮助" << endl; while (cout << p.gets() << ">" , gets(cmd)){ Scanner s(cmd); string one = s.next(); if (one == "")continue; else if (one == "format"){ cout << "格式化将会清空全部文件及文件夹" << endl; cout << "您真的要清空吗?(Y/N)" << endl; gets(cmd); Scanner ss = Scanner(cmd); string c = ss.next(); if (c == "y" || c == "Y") format(), start(),p.home(), cout << "格式化成功" << endl; else cout << "取消格式化" << endl; start(); } else if (one == "help"){ cout << "您可以使用以下指令" << endl; help(); } else if (one == "ls"){ cout << p.gets() << endl; ls(p.peek().block); } else if (one == "home"){ p.home(); } else if (one == "back"){ p.pop(); } else if (one == "exit"){ break; } else if (one == "tree"){ Item it = p.peek(); string tr = ""; cout << "---------------------------" << endl; tree(it.block, it.name, , "", tr); cout << "---------------------------" << endl; cout << tr << endl; } else if (one == "del"){ if (s.hasNext() == false){ cout << "命令格式错误,缺少文件名" << endl; continue; } string file = s.next(); const char *name = file.c_str(); || !exist(p.peek().block, name)){ cout << "不存在这样的文件" << endl; continue; } Item it = getItem(p.peek().block, name); deleteItem(p.peek().block, name); } else if (one == "newfile" || one == "newfolder"){ if (s.hasNext() == false){ cout << "命令格式错误,缺少文件名" << endl; continue; } string file = s.next(); const char *name = file.c_str(); ){ cout << "文件名太长" << endl; continue; } if (exist(p.peek().block, name)){ cout << "已经存在名为" << file << "的文件了" << endl; continue; } bool isFile = (one == "newfile"); addItem(p.peek().block, name, isFile); } else if (one == "cd"){ if (s.hasNext() == false){ cout << "命令格式错误" << endl; continue; } string son = s.next(); const char* name = son.c_str(); || !exist(p.peek().block, name)){ cout << "不存在这样的文件" << endl; continue; } Item it = getItem(p.peek().block, name); if (it.isFile){ cout << "不能进入文件,请输入文件夹" << endl; continue; } p.push(it); } else if (one == "show"){ if (s.hasNext() == false){ cout << "命令格式错误" << endl; continue; } string son = s.next(); const char* name = son.c_str(); || exist(p.peek().block, name) == ){ cout << "不存在这样的文件" << endl; continue; } Item it = getItem(p.peek().block, name); ){ cout << son << "不是文件,而是文件夹" << endl; continue; } ]; readFile(it.block, content); cout << content << endl; } else if (one == "del"){ if (s.hasNext() == false){ cout << "命令格式错误" << endl; continue; } string son = s.next(); const char*name = son.c_str(); || exist(p.peek().block, name) == ){ cout << "不存在这样的文件" << endl; continue; } Item it = getItem(p.peek().block, name); deleteItem(p.peek().block, it.name); } else if (one == "writefile"){ if (s.hasNext() == false){ cout << "命令格式错误" << endl; continue; } string son = s.next(); const char*name = son.c_str(); || exist(p.peek().block, name) == ){ cout << "不存在这样的文件" << endl; continue; } Item it = getItem(p.peek().block, name); ){ cout << "不能往文件夹中写内容" << endl; continue; } if (s.hasNext() == false){ cout << "命令格式错误" << endl; continue; } string fin = s.next(); FILE*ff = fopen(fin.c_str(), "r"); ){ cout << "不存在名为" << fin << "的子文件" << endl; continue; } int len = filelen(ff); - ){ cout << fin << "文件太长" << endl; continue; } ]; fseek(ff, , ); fread(content, len, , ff); content[len] = ; writeFile(it.block, content); fclose(ff); delete content; } else if (one == "debug"){ cout << "------------" << endl; debugGroup(); cout << endl; } else { cout << "没有这样的命令,请输入help查看可用命令" << endl; } //这句话本来该省略,之所以加在这里是为了防止不用exit命令退出,那样会破坏系统. writeBlock(, &super); } } int main(){ start(); run(); exit(); ; }