Basic Framework
fileModel.java
package File_System_Structure;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class fileModel {
//fileModel類用來(lái)記錄文件或目錄的相關(guān)屬性
public Map<String, fileModel> subMap = new HashMap<String, fileModel>();
private String name; //文件名或目錄名
private String type; //文件類型
private int attr; //用來(lái)識(shí)別是文件還是目錄
private int startNum; //在FAT表中起始位置
private int size; //文件的大小
private fileModel father = null; //該文件或目錄的上級(jí)目錄
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.java
package File_System_Structure;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class OSManager {
//OSManager這個(gè)類實(shí)現(xiàn)對(duì)文件的各種操作
public Map<String, fileModel> totalFiles = new HashMap<String, fileModel>();
//定義FAT表
private int[] fat = new int[128];
//創(chuàng)建根目錄 使用fat表的第一項(xiàng)
private fileModel root = new fileModel("root", 1);
private fileModel nowCatalog = root;
public OSManager() {
//將FAT表初始化全部為0炎咖,并將第一位設(shè)為根目錄的空間
for( int i = 0; i < fat.length ; i++ ) {
fat[i] = 0;
}
fat[ 1 ] = 255; //255表示磁盤塊已占用
fat[ 0 ] = 126; //紀(jì)錄磁盤剩余塊數(shù)
root.setFather( root );
totalFiles.put( "root", root );
}
public int setFat(int size) {
int[] startNum = new int[128];
int i = 2; //紀(jì)錄fat循環(huán)定位
for( int j = 0; j < size; i++ ) {
if( fat[ i ] == 0 ) {
startNum[ j ] = i; //紀(jì)錄該文件所有磁盤塊
if( j > 0 ) {
fat[ startNum[ j-1 ] ] = i; //fat上一磁盤塊指向下一磁盤塊地址
}
j++;
}
}
fat[ i-1 ] = 255;
return startNum[ 0 ]; //返回該文件起始?jí)K盤號(hào)
}
/*
*
* 該方法用于刪除時(shí)釋放FAT表的空間
*/
public void deleteFAT( 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;
}
/*
*
* 以下為追加內(nèi)容時(shí)修改fat表
*
*/
public void AddFAT(int startNum, int addSize) {
int nowPoint = startNum;
int nextPoint = fat[startNum];
while( fat[ nowPoint ] != 255 ) {
nowPoint = nextPoint;
nextPoint = fat[ nowPoint ];
}//找到該文件終結(jié)盤塊
for( int i = 2, count = 0; count < addSize; i++ ) {
if( fat[ i ] == 0 ) {
fat[ nowPoint ] = i;
nowPoint = i;
count++;
fat[ nowPoint ] = 255;//作為當(dāng)前文件終結(jié)盤塊
}
}
}
/*
* 以下為創(chuàng)建文件和目錄方法
*
*/
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 ) { //若存在同名目錄 繼續(xù)創(chuàng)建文件
int startNum = setFat( size );
fileModel file = new fileModel( name, type, startNum, size );
file.setFather( nowCatalog ); //紀(jì)錄上一層目錄
nowCatalog.subMap.put( name, file ); //在父目錄添加該文件
totalFiles.put( file.getName(), file );
fat[ 0 ] -= size;
System.out.println( "File is successfully created!" );
showFile();
} else if( value.getAttr() == 2 ) { //若同名文件已存在绒极,創(chuàng)建失敗
System.out.println("File fails to create because the file already exists");
showFile();
}
} else if( value == null ) { //若無(wú)同名文件或文件夾,繼續(xù)創(chuàng)建文件
int startNum = setFat( size );
fileModel file = new fileModel( name, type, startNum, size );
file.setFather( nowCatalog ); //紀(jì)錄上一層目錄
nowCatalog.subMap.put( name, file ); //在父目錄添加該文件
totalFiles.put( file.getName(), file );
fat[0] -= size;
System.out.println( "File is successfully created!");
showFile();
}
} else {
System.out.println("File fails to create because insufficient disk space!");
}
}
public void createCatolog( String name ) {
if( fat[ 0 ] >= 1 ) { //判斷磁盤空間是否足夠創(chuàng)建文件夾
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 ); //紀(jì)錄上一層目錄
nowCatalog.subMap.put( name, catalog );
fat[ 0 ]--;
totalFiles.put( catalog.getName(), catalog );
System.out.println( "Directory is successfully created!" );
showFile();
}
else if(value.getAttr() == 3) {
System.out.println( "Directory fails to create because the directory already exists!" );
showFile();
}
}
else if(value == null) {
int startNum = setFat(1);
fileModel catalog = new fileModel( name, startNum );
catalog.setFather( nowCatalog ); //紀(jì)錄上一層目錄
nowCatalog.subMap.put( name, catalog );
fat[ 0 ]--;
totalFiles.put( catalog.getName(), catalog );
System.out.println( "Directory is successfully created!" );
showFile();
}
}
else {
System.out.println("Directory fails to create because insufficient disk space!");
}
}
/*
*
* 以下為顯示該目錄下的所有文件信息
*
*/
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("File Name:" + value.getName());
System.out.println("Operation Type:" + "Folder");
System.out.println("Starting Disk Blocks:" + value.getStartNum());
System.out.println("Size: " + value.getSize());
System.out.println("<-------------------------------------->");
}
else if(value.getAttr() == 2) {
System.out.println("File Name:" + value.getName() + "." + value.getType());
System.out.println("Operation Type: " + "Readable & Writable File");
System.out.println("Starting Disk Blocks:" + value.getStartNum());
System.out.println("Size:" + value.getSize());
System.out.println("<-------------------------------------->");
}
}
}
for(int i =0; i<2; i++)
System.out.println();
System.out.println("Disk Surplus Space:" + fat[ 0 ] + " " + "Exit the system please enter:exit");
System.out.println();
}
/*
*
* 以下為刪除該目錄下某個(gè)文件
*
*/
public void deleteFile(String name) {
fileModel value = nowCatalog.subMap.get( name );
if( value == null ) {
System.out.println("Delete failed, No File or Folder!!");
}
else if( !value.subMap.isEmpty() ){
System.out.println("Delete failed because the folder contains files!");
}
else {
nowCatalog.subMap.remove(name);
deleteFAT(value.getStartNum());
if(value.getAttr() == 3) {
System.out.println("Folder " + value.getName() + " Have been successfully deleted");
showFile();
}
else if(value.getAttr() == 2) {
System.out.println("File " + value.getName() + "Have been successfully deleted");
showFile();
}
}
}
/*
*
* 以下為文件或文件夾重命名方法
*
*/
public void reName(String name, String newName) {
if( nowCatalog.subMap.containsKey(name) ) {
if( nowCatalog.subMap.containsKey( newName ) ) {
System.out.println("Rename failed because the same name file already exists!");
showFile();
}
else {
fileModel value = nowCatalog.subMap.get( name );
value.setName( newName );
nowCatalog.subMap.remove( name );
nowCatalog.subMap.put( newName, value );
System.out.println( "Rename has succeed" );
System.out.println();
showFile();
}
}
else {
System.out.println("Rename failed because there is no this file");
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("Modify type success!");
showFile();
}
else if(value.getAttr() == 3) {
System.out.println("Change error because the folder can not modify type!货葬!");
openFile( value.getName() );
}
}
else {
System.out.println("Modify error, please check whether the input file name is correct!");
}
}
/*
* 以下為打開文件或文件夾方法
*
*/
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("The file has been opened and the file size is: " + value.getSize() );
}
else if(value.getAttr() == 3) {
nowCatalog = value;
System.out.println("The file has been opened!");
showFile();
}
}
else{
System.out.println("Open failed because the file does not exist!");
}
}
/*
*
* 以下為向文件追加內(nèi)容方法
* 追加內(nèi)容需要打開文件后才能操作
*/
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);
AddFAT(value.getStartNum(), addSize);
System.out.println("Addition content is successful! The file is being reopened...");
openFile(name);
}
else{
System.out.println("The appended content failed, please verify that the filename is entered correctly.");
}
}
}
else{
System.out.println("Addition content is failed because insufficient memory space");
}
}
/*
*
* 以下為返回上一層目錄
*
*/
public void backFile() {
if(nowCatalog.getFather() == null) {
System.out.println("The document does not have a superior directory!");
} else {
nowCatalog = nowCatalog.getFather();
showFile();
}
}
/*
* 以下根據(jù)絕對(duì)路徑尋找文件
*
*/
public void searchFile(String[] roadName) {
fileModel theCatalog = nowCatalog; //設(shè)置斷點(diǎn)紀(jì)錄當(dāng)前目錄
if( totalFiles.containsKey(roadName[roadName.length-1]) ) { //檢查所有文件中有無(wú)該文件
nowCatalog = root; //返回根目錄
if( nowCatalog.getName().equals( roadName[0]) ) { //判斷輸入路徑的首目錄是否root
System.out.println("yes");
for( int i = 1; i < roadName.length; i++ ) {
if( nowCatalog.subMap.containsKey( roadName[ i ] ) ) {
nowCatalog = nowCatalog.subMap.get( roadName[ i ] ); //一級(jí)一級(jí)往下查
}
else {
System.out.println("Can't find the file or directory under this path, please check whether the path is correct!");
nowCatalog = theCatalog;
showFile();
break;
}
}
if( roadName.length > 1 ){
nowCatalog = nowCatalog.getFather(); //返回文件上一級(jí)目錄
showFile();
}
}
else{
nowCatalog = theCatalog;
System.out.println("Please enter the correct absolute path浮定!");
showFile();
}
}
else{
System.out.println("This file or directory does not exist, please enter the correct absolute path征讲!");
showFile();
}
}
/*
* 以下為打印FAT表內(nèi)容
*
*/
public void showFAT() {
for(int j=0; j<125; j+=5) {
System.out.println("第幾項(xiàng) | " + j + " " + (j+1) + " " + (j+2) + " "
+ (j+3) + " " + (j+4));
System.out.println("內(nèi)容 | " + fat[j] + " " + fat[j+1] + " " + fat[j+2]
+ " " + fat[j+3] + " " + fat[j+4]);
System.out.println();
}
int j = 125;
System.out.println("第幾項(xiàng) | " + j + " " + (j+1) + " " + (j+2));
System.out.println("內(nèi)容 | " + fat[j] + " " + fat[j+1] + " " + fat[j+2]);
System.out.println();
showFile();
}
}
testFileSystem.java
package File_System_Structure;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
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("***********" + "Welcome to use the file simulation operating system" + "***********");
System.out.println();
manager.showFile();
System.out.println("Please enter command line(Enter help to view the command table):");
while ((str = s.nextLine()) != null) {
if (str.equals("exit")) {
System.out.println("Thank you!");
break;
}
String[] strs = editStr(str);
switch (strs[0]) {
case "createFile":
if (strs.length < 4) {
System.out.println("The command you have entered is incorrect. Please check it.");
}
else {
manager.createFile(strs[1], strs[2],
Integer.parseInt(strs[3]));
}
break;
case "createCatalog":
if (strs.length < 2) {
System.out.println("The command you have entered is incorrect. Please check it.");
}
else {
manager.createCatolog(strs[1]);
}
break;
case "open":
if (strs.length < 2) {
System.out.println("The command you have entered is incorrect. Please check it.");
}
else {
manager.openFile(strs[1]);
}
break;
case "cd":
if (strs.length < 2) {
System.out.println("The command you have entered is incorrect. Please check it.");
}
else {
manager.openFile(strs[1]);
}
break;
case "cd..":
manager.backFile();
break;
case "delete":
if (strs.length < 2) {
System.out.println("The command you have entered is incorrect. Please check it.");
}
else {
manager.deleteFile(strs[1]);
}
break;
case "rename":
if (strs.length < 3) {
System.out.println("The command you have entered is incorrect. Please check it.");
}
else {
manager.reName(strs[1], strs[2]);
}
break;
case "search": {
if (strs.length < 2) {
System.out.println("The command you have entered is incorrect. Please check it.");
}
else {
String[] roadName = strs[1].split("/");
manager.searchFile(roadName);
}
break;
}
case "showFAT":
manager.showFAT();
break;
case "addContents":
if (strs.length < 3) {
System.out.println("The command you have entered is incorrect. Please check it.");
}
else {
manager.reAdd(strs[1], Integer.parseInt(strs[2]));
}
break;
case "changeType":
if (strs.length < 3) {
System.out.println("The command you have entered is incorrect. Please check it.");
} else {
manager.changeType(strs[1], strs[2]);
}
break;
case "help": {
System.out.println("The commands are as follows(Space cannot be omitted):");
System.out
.println("createFile FileName fileType fileSize");
System.out.println("<Create a file, for instance:createFile PUSU txt 5 >");
System.out.println();
System.out
.println("createCatalog FatalogName");
System.out.println("<Create a directory, for instance:createCatalog myFile >");
System.out.println();
System.out
.println("open Name.FileTypt");
System.out.println("<Open a file, for instance:open PUSU.txt >");
System.out.println();
System.out.println("cd CatalogName");
System.out.println("<Open a directory, for instance: cd myFile >");
System.out.println();
System.out.println("cd..");
System.out.println("<Return to the superior directory, for instance: cd..");
System.out.println();
System.out
.println("delete FileName/CatalogName");
System.out.println("<Delete a files or a directory (the directory must be empty), for instance:delete PUSU >");
System.out.println();
System.out
.println("rename FileName/CatalogName NewName");
System.out.println("<rename a file or a directory, for instance: rename myfile mycomputer >");
System.out.println();
System.out
.println("search FileAbsolutedRoad/CatalogAbsolutedRoad");
System.out.println("<Finding a file or directory based on an absolute path, for instance: search root/marco >");
System.out.println();
System.out.println("showFAT");
System.out.println("<Look at the FAT table, for instance: showFAT>");
System.out.println();
System.out.println();
System.out.println("The following command needs to open the file before:");
System.out
.println("addContents FileName ContentSize");
System.out.println("<Add content to a file, for instance:ddContents PUSU 4 >");
System.out.println();
System.out
.println("changeType FileName newType");
System.out.println("<Change file type, for instance: changeType PUSU doc>");
System.out.println();
break;
}
default:
for(String st : strs)
System.out.println(st);
System.out.println("The command you have entered is incorrect. Please check it.");
}
System.out.println("Please enter command line(Enter help to view the command table)::");
}
}
public static String[] editStr(String str) {
Pattern pattern = Pattern.compile("([a-zA-Z0-9.\\\\/]*) *");// 根據(jù)空格分割輸入命令
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++) { // 判斷除命令以外每一個(gè)參數(shù)中是否含有 "."
int j = strs[i].indexOf(".");
if (j != -1) { // 若含有"." 將其切割 取前部分作為文件名
String[] index = strs[i].split("\\."); // 使用轉(zhuǎn)義字符"\\."
strs[i] = index[0];
}
}
return strs;
}
}
Running Effect
Source Download
Please click the address->File System Structure
Summarize
用java語(yǔ)言模擬操作系統(tǒng)中的文件管理系統(tǒng),文件模擬磁盤寄纵,數(shù)組模擬緩沖區(qū)鳖敷,其中:
- 支持多級(jí)目錄結(jié)構(gòu),支持文件的絕對(duì)讀路徑程拭;
- 文件的邏輯結(jié)構(gòu)采用流式結(jié)構(gòu)定踱,物理結(jié)構(gòu)采用鏈接結(jié)構(gòu)中的顯式鏈接方式;
- 采用文件分配表FAT恃鞋;
- 實(shí)現(xiàn)的命令包括建立目錄崖媚、列目錄、刪除空目錄恤浪、建立文件畅哑、刪除文件、顯示
文件內(nèi)容水由、打開文件荠呐、讀文件、寫文件砂客、關(guān)閉文件泥张、改變文件屬性【现担可以采用
命令行界面執(zhí)行這些命令媚创,也可以采用“右擊快捷菜單選擇”方式執(zhí)行命令。 - 后編寫主函數(shù)對(duì)所作工作進(jìn)行測(cè)試齿诉。