Basic Framework
fileModel.java
package File_System_Structure;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class fileModel {
//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.java
package File_System_Structure;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class OSManager {
//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() {
//将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 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;
}
/*
*
* 以下为追加内容时修改fat表
*
*/
public void AddFAT(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;//作为当前文件终结盘块
}
}
}
/*
* 以下为创建文件和目录方法
*
*/
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( "File is successfully created!" );
showFile();
} else if( value.getAttr() == 2 ) { //若同名文件已存在,创建失败
System.out.println("File fails to create because the file already exists");
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( "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 ) { //判断磁盘空间是否足够创建文件夹
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( "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 ); //纪录上一层目录
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();
}
/*
*
* 以下为删除该目录下某个文件
*
*/
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!");
}
}
/*
*
* 以下为向文件追加内容方法
* 追加内容需要打开文件后才能操作
*/
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();
}
}
/*
* 以下根据绝对路径寻找文件
*
*/
public void searchFile(String[] roadName) {
fileModel theCatalog = nowCatalog; //设置断点纪录当前目录
if( totalFiles.containsKey(roadName[roadName.length-1]) ) { //检查所有文件中有无该文件
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 ] ); //一级一级往下查
}
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(); //返回文件上一级目录
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表内容
*
*/
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.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.\\\\/]*) *");// 根据空格分割输入命令
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;
}
}
Running Effect
Source Download
Please click the address->File System Structure
Summarize
用java语言模拟操作系统中的文件管理系统,文件模拟磁盘,数组模拟缓冲区,其中:
- 支持多级目录结构,支持文件的绝对读路径;
- 文件的逻辑结构采用流式结构,物理结构采用链接结构中的显式链接方式;
- 采用文件分配表FAT;
- 实现的命令包括建立目录、列目录、删除空目录、建立文件、删除文件、显示
文件内容、打开文件、读文件、写文件、关闭文件、改变文件属性。可以采用
命令行界面执行这些命令,也可以采用“右击快捷菜单选择”方式执行命令。 - 后编写主函数对所作工作进行测试。