這是我前段時間做了一個操作系統課程設計作業,使用java實現了命令行輸入對虛擬文件進行管理。
下面是課程設計要求:
點擊這里可以查看詳細的要求
題目五 ?模擬磁盤文件系統實現?
一、課程設計目的?
了解磁盤文件系統的結構、功能和實現。并可練習合作完成系統的團隊精神和提高
程序設計能力。?
二、小組人數 建議 3~5 人一組共同完成模擬磁盤文件系統的實現。 選擇題目“模擬磁盤文件系統實現”的小組在最終提交時須公開演示及講解。 由于這個題目較復雜,難度和工作量遠大于前面幾個題目,故小組成員最后得分 也酌情高于選擇前面四個題目的同學的分數(高 5~10 分)。 三、編程語言?
建議使用一些 Windows 環境下的程序設計語言如 VC、Java,以借助這些語言的多
線程來模擬并行發生的行為。要求圖形界面。?
四、課程設計內容?
設計一個簡單的文件系統,用文件模擬磁盤,用數組模擬緩沖區,要求:?
(1) 支持多級目錄結構,支持文件的絕對讀路徑;?
(2) 文件的邏輯結構采用流式結構,物理結構采用鏈接結構中的顯式鏈接方式;?
(3) 采用文件分配表 FAT;?
(4) 實現的命令包括建立目錄、列目錄、刪除空目錄、建立文件、刪除文件、顯示
文件內容、打開文件、讀文件、寫文件、關閉文件、改變文件屬性。可以采用
命令行界面執行這些命令,也可以采用“右擊快捷菜單選擇”方式執行命令。?
(5) 后編寫主函數對所作工作進行測試。?
下面是我實現的功能:
以下為源代碼
首先是一個FileModel類用來記錄文件或目錄的相關屬性
package com.model;import java.util.ArrayList;
import java.util.HashMap;import java.util.Map;public class FileModel {public Map<String, FileModel> subMap = new HashMap<String, FileModel>();private String name; //文件名或目錄名private String type; //文件類型private int attr; //用來識別是文件還是目錄 private int startNum; //在FAT表中起始位置private int size; //文件的大小private FileModel father = null; //該文件或目錄的上級目錄public FileModel(String name, String type, int startNum, int size){this.name = name;this.type = type;this.attr = 2;this.startNum = startNum;this.size = size; }public FileModel(String name, int startNum) {this.name = name;this.attr = 3;this.startNum = startNum;this.type = " ";this.size = 1;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getType() {return type;}public void setType(String type) {this.type = type;}public int getAttr() {return attr;}public void setAttr(int attr) {this.attr = attr;}public int getStartNum() {return startNum;}public void setStartNum(int startNum) {this.startNum = startNum;}public int getSize() {return size;}public void setSize(int size) {this.size = size;}public FileModel getFather() {return father;}public void setFather(FileModel father) {this.father = father;}}
接著使用OSManager這個類實現對文件的各種操作
package com.service;import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;import com.model.FileModel;
import com.sun.xml.internal.bind.v2.util.FatalAdapter;public class OSManager {public Map<String, FileModel> totalFiles = new HashMap<String, FileModel>();//定義FAT表private int[] fat = new int[128]; //創建根目錄 使用fat表的第一項private FileModel root = new FileModel("root", 1);private FileModel nowCatalog = root;public OSManager() {// TODO Auto-generated consructor stub//將FAT表初始化全部為0,并將第一位設為根目錄的空間for(int i=0; i<fat.length ; i++ ) {fat[i] = 0;}fat[1] = 255; //255表示磁盤塊已占用fat[0] = 126; //紀錄磁盤剩余塊數 root.setFather(root);totalFiles.put("root", root);}public int setFat(int size) {int[] startNum = new int[128];int i = 2; //紀錄fat循環定位for(int j=0; j<size; i++) {if(fat[i] == 0) {startNum[j] = i; //紀錄該文件所有磁盤塊if(j>0) {fat[startNum[j-1]] = i; //fat上一磁盤塊指向下一磁盤塊地址}j++;}}fat[i-1] = 255;return startNum[0]; //返回該文件起始塊盤號}/** * 該方法用于刪除時釋放FAT表的空間*/public void delFat(int startNum) {int nextPoint = fat[startNum];int nowPoint = startNum;int count = 0;while(fat[nowPoint] != 0) {nextPoint = fat[nowPoint];if(nextPoint == 255) {fat[nowPoint] =0;count++;break;} else {fat[nowPoint] = 0;count++;nowPoint = nextPoint;}}fat[0] += count;}/** * 以下為追加內容時修改fat表* */public void reAddFat(int startNum, int addSize) {int nowPoint = startNum;int nextPoint = fat[startNum];while(fat[nowPoint] != 255) {nowPoint = nextPoint;nextPoint = fat[nowPoint];}//找到該文件終結盤塊for(int i=2, count = 0; count <addSize ; i++ ) {if(fat[i] == 0) {fat[nowPoint] = i;nowPoint = i;count++;fat[nowPoint] = 255;//作為當前文件終結盤塊}}}/** 以下為創建文件和目錄方法* 14R5黎志亮 */public void createFile(String name, String type, int size) {if(fat[0] >= size) { //判斷磁盤剩余空間是否足夠建立文件FileModel value = nowCatalog.subMap.get(name); //該目錄下是否尋找同名目錄或文件if(value != null) { //判斷該文件是否存在if(value.getAttr() == 3) { //若存在同名目錄 繼續創建文件int startNum = setFat(size); FileModel file = new FileModel(name, type, startNum, size);file.setFather(nowCatalog); //紀錄上一層目錄nowCatalog.subMap.put(name, file); //在父目錄添加該文件totalFiles.put(file.getName(), file);fat[0] -= size;System.out.println("創建文件成功!");showFile();} else if(value.getAttr() == 2) { //若同名文件已存在,創建失敗System.out.println("創建失敗,該文件已存在!"); showFile();}} else if(value == null) { //若無同名文件或文件夾,繼續創建文件int startNum = setFat(size); FileModel file = new FileModel(name, type, startNum, size);file.setFather(nowCatalog); //紀錄上一層目錄nowCatalog.subMap.put(name, file); //在父目錄添加該文件totalFiles.put(file.getName(), file);fat[0] -= size;System.out.println("創建文件成功!");showFile();}} else {System.out.println("創建文件失敗,磁盤空間不足!");}}public void createCatolog(String name) {if(fat[0] >= 1) { //判斷磁盤空間是否足夠創建文件夾FileModel value = nowCatalog.subMap.get(name); //判斷該目錄下是否存在同名目錄或文件if(value != null) {if(value.getAttr() == 2) {int startNum = setFat(1);FileModel catalog = new FileModel(name, startNum);catalog.setFather(nowCatalog); //紀錄上一層目錄nowCatalog.subMap.put(name, catalog);fat[0]--;totalFiles.put(catalog.getName(), catalog);System.out.println("創建目錄成功!");showFile();} else if(value.getAttr() == 3) {System.out.println("創建目錄失敗,該目錄已存在!");showFile();} } else if(value == null) {int startNum = setFat(1);FileModel catalog = new FileModel(name, startNum);catalog.setFather(nowCatalog); //紀錄上一層目錄nowCatalog.subMap.put(name, catalog);fat[0]--;totalFiles.put(catalog.getName(), catalog);System.out.println("創建目錄成功!");showFile();} } else {System.out.println("創建目錄失敗,磁盤空間不足!");}}/** * 以下為顯示該目錄下的所有文件信息* */public void showFile() {System.out.println("***************** < " + nowCatalog.getName() + " > *****************");if(!nowCatalog.subMap.isEmpty()) {for(FileModel value : nowCatalog.subMap.values()) {if(value.getAttr() == 3) { //目錄文件System.out.println("文件名 : " + value.getName());System.out.println("操作類型 : " + "文件夾");System.out.println("起始盤塊 : " + value.getStartNum());System.out.println("大小 : " + value.getSize());System.out.println("<-------------------------------------->");}else if(value.getAttr() == 2) {System.out.println("文件名 : " + value.getName() + "." + value.getType());System.out.println("操作類型 : " + "可讀可寫文件");System.out.println("起始盤塊 : " + value.getStartNum());System.out.println("大小 : " + value.getSize());System.out.println("<-------------------------------------->");}}}for(int i =0; i<2; i++) System.out.println();System.out.println("磁盤剩余空間 :" + fat[0] + " " + "退出系統請輸入exit");System.out.println();}/** * 以下為刪除該目錄下某個文件* */public void deleteFile(String name) {FileModel value = nowCatalog.subMap.get(name);if(value == null) {System.out.println("刪除失敗,沒有該文件或文件夾!");} else if(!value.subMap.isEmpty()) {System.out.println("刪除失敗,該文件夾內含有文件!");} else {nowCatalog.subMap.remove(name);delFat(value.getStartNum());if(value.getAttr() == 3) {System.out.println("文件夾 " + value.getName() + " 已成功刪除");showFile();} else if(value.getAttr() == 2) {System.out.println("文件 " + value.getName() + "已成功刪除");showFile();}}}/** * 以下為文件或文件夾重命名方法* */public void reName(String name, String newName) {if(nowCatalog.subMap.containsKey(name)) {if(nowCatalog.subMap.containsKey(newName)) {System.out.println("重命名失敗,同名文件已存在!"); showFile();} else {//nowCatalog.subMap.get(name).setName(newName);FileModel value = nowCatalog.subMap.get(name);value.setName(newName);nowCatalog.subMap.remove(name);nowCatalog.subMap.put(newName, value);System.out.println("重命名成功!");System.out.println();showFile();}} else {System.out.println("重命名失敗,沒有該文件!");showFile();}}/** * 以下為修改文件類型* 修改類型需要打開文件后才能操作*/public void changeType(String name, String type) {nowCatalog = nowCatalog.getFather();if(nowCatalog.subMap.containsKey(name)) {FileModel value = nowCatalog.subMap.get(name);if(value.getAttr() == 2) {value.setType(type);nowCatalog.subMap.remove(name);nowCatalog.subMap.put(name, value);System.out.println("修改類型成功!");showFile();} else if(value.getAttr() == 3) {System.out.println("修改錯誤,文件夾無法修改類型!");openFile(value.getName());}} else {System.out.println("修改錯誤,請檢查輸入文件名是否正確!");}}/** 以下為打開文件或文件夾方法* */public void openFile(String name) {if(nowCatalog.subMap.containsKey(name)) {FileModel value = nowCatalog.subMap.get(name);if(value.getAttr() == 2) {nowCatalog = value;System.out.println("文件已打開,文件大小為 : " + value.getSize()); } else if(value.getAttr() == 3) {nowCatalog = value;System.out.println("文件夾已打開!");showFile();}} else {System.out.println("打開失敗,文件不存在!");}}/** * 以下為向文件追加內容方法* 追加內容需要打開文件后才能操作*/public void reAdd(String name, int addSize) {if(fat[0] >= addSize) {nowCatalog = nowCatalog.getFather();if(nowCatalog.subMap.containsKey(name)) {FileModel value = nowCatalog.subMap.get(name);if(value.getAttr() == 2) {value.setSize(value.getSize() + addSize);reAddFat(value.getStartNum(), addSize);System.out.println("追加內容成功!正在重新打開文件...");openFile(name);} else{System.out.println("追加內容失敗,請確認文件名是否正確輸入。"); }} else {System.out.println("追加內容失敗,請確認文件名是否正確輸入!");showFile();}} else {System.out.println("追加內容失敗,內存空間不足!");}}/** * 以下為返回上一層目錄* */public void backFile() {if(nowCatalog.getFather() == null) {System.out.println("該文件沒有上級目錄!");} else {nowCatalog = nowCatalog.getFather();showFile();}}/** 以下根據絕對路徑尋找文件* */public void searchFile(String[] roadName) {FileModel theCatalog = nowCatalog; //設置斷點紀錄當前目錄if(totalFiles.containsKey(roadName[roadName.length-1])) { //檢查所有文件中有無該文件nowCatalog = root; //返回根目錄if(nowCatalog.getName().equals(roadName[0])) { //判斷輸入路徑的首目錄是否rootSystem.out.println("yes");/*for(String temp:roadName)System.out.println(temp);*/for(int i=1; i<roadName.length; i++) {if(nowCatalog.subMap.containsKey(roadName[i])) {/*System.out.println(nowCatalog.getName());for(Entry<String, FileModel> s : nowCatalog.subMap.entrySet())System.out.println("鍵值對:" + s.getValue().getName());*/nowCatalog = nowCatalog.subMap.get(roadName[i]); //一級一級往下查} else {System.out.println("找不到該路徑下的文件或目錄,請檢查路徑是否正確");nowCatalog = theCatalog;showFile();break;}}if(roadName.length>1){nowCatalog = nowCatalog.getFather(); //返回文件上一級目錄 showFile();}} else {nowCatalog = theCatalog;System.out.println("請輸入正確的絕對路徑!");showFile();}} else {System.out.println("該文件或目錄不存在,請輸入正確的絕對路徑!");showFile();}}/** 以下為打印FAT表內容* */public void showFAT() {for(int j=0; j<125; j+=5) {System.out.println("第幾項 | " + j + " " + (j+1) + " " + (j+2) + " "+ (j+3) + " " + (j+4));System.out.println("內容 | " + fat[j] + " " + fat[j+1] + " " + fat[j+2]+ " " + fat[j+3] + " " + fat[j+4]);System.out.println();}int j = 125;System.out.println("第幾項 | " + j + " " + (j+1) + " " + (j+2));System.out.println("內容 | " + fat[j] + " " + fat[j+1] + " " + fat[j+2]);System.out.println();showFile();}
}
最后使用TestFileSystem這個類實現菜單功能
package com.testsystem;import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;import com.service.OSManager;public class TestFileSystem {public static void main(String[] args) {try{OSManager manager = new OSManager();meun(manager);} catch (Exception e) {e.printStackTrace();}}public static void meun(OSManager manager) {Scanner s = new Scanner(System.in);String str = null;System.out.println("***********" + "歡迎使用文件模擬操作系統" + "***********");System.out.println();manager.showFile();System.out.println("請輸入命令(輸入help查看命令表):");while ((str = s.nextLine()) != null) {if (str.equals("exit")) {System.out.println("感謝您的使用!");break;}String[] strs = editStr(str);switch (strs[0]) {case "createFile":if (strs.length < 4) {System.out.println("您所輸入的命令有誤,請檢查");} else {manager.createFile(strs[1], strs[2],Integer.parseInt(strs[3]));}break;case "createCatalog":if (strs.length < 2) {System.out.println("您所輸入的命令有誤,請檢查!");} else {manager.createCatolog(strs[1]);}break;case "open":if (strs.length < 2) {System.out.println("您所輸入的命令有誤,請檢查!");} else {manager.openFile(strs[1]);}break;case "cd":if (strs.length < 2) {System.out.println("您所輸入的命令有誤,請檢查!");} else {manager.openFile(strs[1]);}break;case "cd..":manager.backFile();break;case "delete":if (strs.length < 2) {System.out.println("您所輸入的命令有誤,請檢查!");} else {manager.deleteFile(strs[1]);}break;case "rename":if (strs.length < 3) {System.out.println("您所輸入的命令有誤,請檢查!");} else {manager.reName(strs[1], strs[2]);}break;case "search": {if (strs.length < 2) {System.out.println("您所輸入的命令有誤,請檢查!");} else {String[] roadName = strs[1].split("/");/*for(String temp : strs)System.out.println(temp);System.out.println(Arrays.toString(strs));System.out.println(Arrays.toString(roadName));*/manager.searchFile(roadName);}break;}case "showFAT":manager.showFAT();break;case "addContents":if (strs.length < 3) {System.out.println("您所輸入的命令有誤,請檢查!");} else {manager.reAdd(strs[1], Integer.parseInt(strs[2]));}break;case "changeType":if (strs.length < 3) {System.out.println("您所輸入的命令有誤,請檢查!");} else {manager.changeType(strs[1], strs[2]);}break;case "help": {System.out.println("命令如下(空格不能省略):");System.out.println("createFile FileName fileType fileSize");System.out.println("<創建文件 如:createFile marco txt 5 >");System.out.println();System.out.println("createCatalog FatalogName");System.out.println("<創建目錄 如:createCatalog myFile >");System.out.println();System.out.println("open Name.FileTypt");System.out.println("<打開文件 如:open marco.txt >");System.out.println();System.out.println("cd CatalogName");System.out.println("<打開目錄 如: cd myFile >");System.out.println();System.out.println("cd..");System.out.println("<返回上級目錄 如: cd..");System.out.println();System.out.println("delete FileName/CatalogName");System.out.println("<刪除文件或目錄(目錄必須為空)如:delete marco >");System.out.println();System.out.println("rename FileName/CatalogName NewName");System.out.println("<重命名文件或目錄 如: rename myfile mycomputer >");System.out.println();System.out.println("search FileAbsolutedRoad/CatalogAbsolutedRoad");System.out.println("<根據絕對路徑尋找文件或者目錄 如: search root/marco >");System.out.println();System.out.println("showFAT");System.out.println("<查看FAT表 如: showFAT>");System.out.println();System.out.println();System.out.println("下列命令需要打開文件后操作:");System.out.println("addContents FileName ContentSize");System.out.println("<在文件內增加內容 如:ddContents marco 4 >");System.out.println();System.out.println("changeType FileName newType");System.out.println("<改變文件類型 如: changeType marco doc>");System.out.println();break;}default:for(String st : strs)System.out.println(st);System.out.println("您所輸入的命令有誤,請檢查!");}System.out.println("請輸入命令(輸入help查看命令表):");}}public static String[] editStr(String str) {Pattern pattern = Pattern.compile("([a-zA-Z0-9.\\\\/]*) *");// 根據空格分割輸入命令Matcher m = pattern.matcher(str);ArrayList<String> list = new ArrayList<String>();while(m.find()){list.add(m.group(1));}String[] strs = list.toArray(new String[list.size()]);for (int i = 1; i < strs.length; i++) { // 判斷除命令以外每一個參數中是否含有 "."int j = strs[i].indexOf(".");if (j != -1) { // 若含有"." 將其切割 取前部分作為文件名String[] index = strs[i].split("\\."); // 使用轉義字符"\\."strs[i] = index[0];}} return strs;}
}
總結
以上是生活随笔為你收集整理的操作系统课程设计 —— 模拟磁盘文件系统实现 (Java)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。