1. 程式人生 > >檔案系統模擬實現java版

檔案系統模擬實現java版

作業系統課程設計的內容:

編寫程式模擬一個簡單的檔案系統,具體實驗內容如下:

(1)實現多級目錄結構,而非二級目錄結構。

(2)實現檔案和目錄的建立、刪除、重新命名和讀寫許可權控制功能。

(3)實現顯示檔案內容和更改檔案內容的功能。

(4)建立檔案或目錄時,採用動態申請的方式請求儲存空間分配,在刪除檔案或目錄時,還需對申請的空間進行釋放。

(5)為觀察各種命令執行情況,要求以樹形結構直觀地顯示命令執行後的目錄結構。

 

package 檔案系統模擬實現;

import java.awt.Menu;
import java.util.ArrayList;
import java.util.Scanner;

import javax.swing.RootPaneContainer;
//有許可權為1,無許可權為0
public class Main {
	FOLDER root;//根目錄
	int count=0;//控制輸出格式
	int flagD=0;//刪除標記
	public static void main(String[] args) {
		Main init=new Main();
		init.initRootFolder();
		init.menu();
	}
	
	FOLDER findCurrentFolder(FOLDER currentFolder,String name) {//查詢指定目錄
		FOLDER folder;
		if(currentFolder==null)
			return null;		//沒找到
		if(currentFolder.name.equals(name))
			//System.out.println("當前目錄:"+currentFolder.name+" 指定目錄:"+name);
			return currentFolder;		//查詢目錄為當前目錄
		folder=findCurrentFolder(currentFolder.firstChildFolder,name);
		if(folder!=null)
			return folder;		//	查詢目錄在子目錄中
		folder=findCurrentFolder(currentFolder.nextFolder,name);
		if(folder!=null)
			return folder;		//查詢目錄在同級其他目錄中
		return null;		//沒找到
	}
	
	FILE findCurrentFile(FOLDER currentFolder,String name) {//查詢指定檔案
		FILE tempFile;
		if(currentFolder==null)
			return null;		//沒找到
		tempFile=currentFolder.firstChildFile;
		while(tempFile!=null) {//	遍歷當前目錄子檔案
			System.out.println(tempFile.name+" "+name);
			if(tempFile.name.equals(name))
				return tempFile;		//找到了
			tempFile=tempFile.nextFile;
		}
		tempFile=findCurrentFile(currentFolder.firstChildFolder,name);
		if(tempFile!=null)
			return tempFile;		//查詢檔案在子目錄中
		tempFile=findCurrentFile(currentFolder.nextFolder,name);
		if(tempFile!=null)
			return tempFile;		//查詢檔案在同級其他目錄中
		
		return null;		//沒找到
	}
	
	FOLDER prepareWorkBeforeCreate(){
		Scanner in=new Scanner(System.in);
		FOLDER currentFolder=null;
		String name=new String();
		System.out.println("輸入當前目錄名稱:");
		name=in.nextLine();
		
		currentFolder=findCurrentFolder(root,name);
		if(currentFolder==null) {
			System.out.println("目錄不存在!");
			
			return null;
		}
		if(currentFolder.canWrite==0) {
			System.out.println("許可權不夠,無法建立!");
			
			return null;
		}
		
		return currentFolder;
	}
	
	void createFolder() {		//當前目錄中建立新目錄
		Scanner in=new Scanner(System.in);
		FOLDER currentFolder=prepareWorkBeforeCreate();
		if(currentFolder==null) {		//目標目錄不存在
			return;
		}
		String name=new String();
		System.out.println("輸入新目錄名稱:");
		name=in.nextLine();
		
		FOLDER newFolder;
		newFolder=new FOLDER();
		newFolder.name=name;
		newFolder.firstChildFolder=null;		//初始化新目錄
		newFolder.firstChildFile=null;
		newFolder.nextFolder=null;
		newFolder.parentFolder=null;
		newFolder.frontFolder=null;
		newFolder.canRead=1;
		newFolder.canWrite=1;
		
		if(currentFolder.firstChildFolder==null) {		//當前目錄下無子目錄
			currentFolder.firstChildFolder=newFolder;//設定當前目錄的子目錄為新目錄
			newFolder.parentFolder=currentFolder;//新目錄的父目錄為當前目錄
		}
		else {		//當前目錄下有子目錄
			FOLDER tempFolder=currentFolder.firstChildFolder;//儲存當前目錄的子目錄
			FOLDER lastFolder=new FOLDER();		//儲存當前currentFolder下最後一個子folder
			while(tempFolder!=null) {		//	同級目錄下不得有相同的目錄
	            lastFolder=tempFolder;
	            if(tempFolder.name==newFolder.name) {
	            	System.out.println("目錄下已有同名目錄: "+currentFolder.name);
	            	return;
	            }
	            tempFolder=tempFolder.nextFolder;//往下走,遍歷當前目錄下的所有子目錄
	            
			}
			lastFolder.nextFolder=newFolder;		//將新目錄與同級子目錄建立連線
			newFolder.frontFolder=lastFolder;
		}
		System.out.println("建立成功!");
		System.out.println("當前所在目錄名為:"+currentFolder.name);
		System.out.println("建立的目錄名為: "+newFolder.name);
		
	}
	
	void createFile() {		//當前目錄中建立新檔案
		Scanner in=new Scanner(System.in);
		FOLDER currentFolder=prepareWorkBeforeCreate();
		if(currentFolder==null) {//當前目標不存在
			return;
		}
		String name=new String();
		System.out.println("請輸入新檔名稱:");
		name=in.nextLine();
		
		FILE newFile;
		newFile=new FILE();
		newFile.name=name;
		System.out.println("是否輸入檔案內容?是,請輸入y:");
		String ans=in.nextLine();
		System.out.println("ans:"+ans);
		if(ans.equals("y")) {
			System.out.println("請輸入檔案內容:");
			newFile.content=in.nextLine();
			
		}
		else {
			newFile.content="";
		}
		
		
		newFile.nextFile=null;		//初始化新檔案資訊
		newFile.frontFile=null;
		newFile.parentFolder=null;
		newFile.canRead=1;
		newFile.canWrite=1;
		
		if(currentFolder.firstChildFile==null) {		//當前目錄下無子檔案
			currentFolder.firstChildFile=newFile;
			newFile.parentFolder=currentFolder;
		}
		else {		//當前目錄下有子檔案
			FILE tempFile=currentFolder.firstChildFile;
			FILE lastFile=new FILE();		//儲存當前currentFolder下最後一個子檔案
			
			while(tempFile!=null) {		//同級目錄下不得有相同檔案
				lastFile=tempFile;
				if(tempFile.name==newFile.name) {
					System.out.println("目錄下已有同名檔案:"+currentFolder.name);
					return;
				}
				tempFile=tempFile.nextFile;
			}
			lastFile.nextFile=newFile;		//將新檔案與同級檔案建立連線
			newFile.frontFile=lastFile;
		
		}
		System.out.println("建立成功!");
	}
	
	/*void inputName(String name) {
		Scanner in = new Scanner(System.in);
		System.out.println("輸入名稱:");
		name=(in.nextLine());
		
	}*/
	
	void deleteAllChild(FOLDER currentFolder) {		//刪除該目錄下所有內容
		FILE tempFile,dFile;
		if(currentFolder==null)
			return;
		if(flagD==0)
			deleteAllChild(currentFolder.nextFolder);
		flagD=1;
		deleteAllChild(currentFolder.firstChildFolder);//遍歷子目錄
		tempFile=currentFolder.firstChildFile;
		while(tempFile!=null) {//刪除該目錄子檔案
			dFile=tempFile;
			tempFile=tempFile.nextFile;
		}
	}
	
	void deleteFoder() {//刪除目錄所有內容
		Scanner in=new Scanner(System.in);
		String name=new String();
		System.out.println("請輸入要刪除的目錄名稱:");
		name=in.nextLine();
		if(name=="root") {
			System.out.println("根目錄不能刪除!");
			return;
		}
		FOLDER currentFolder=findCurrentFolder(root, name);//先在根目錄中找到當前目錄
		if(currentFolder==null) {
			System.out.println("目錄不存在!");
			return;
		}
		if(currentFolder.canWrite==0) {
			System.out.println("許可權不夠,無法刪除!");
			return ;
		}
		if(currentFolder.frontFolder==null) {//如果當前目錄是父級目錄的第一個目錄
			currentFolder.parentFolder.firstChildFolder=currentFolder.nextFolder;//斷開連線
			if(currentFolder.nextFolder!=null)
				currentFolder.nextFolder.frontFolder=null;//設定當前目錄的下一個目錄為父級目錄的第一個目錄
		}
		else
			currentFolder.frontFolder.nextFolder=currentFolder.nextFolder;//連線當前目錄的上一個目錄和下一個目錄
		deleteAllChild(currentFolder);//釋放空間
		System.out.println("刪除成功!");
	}
	
	void deleteFile() {//刪除檔案
	String name=new String();
	Scanner in=new Scanner(System.in);
	System.out.println("請輸入要刪除的檔名稱:");
	name=in.nextLine();
	FILE currentFile=findCurrentFile(root, name);
	if(currentFile==null) {
		System.out.println("檔案不存在!");
		return;
	}
	if(currentFile.frontFile==null) {
		currentFile.parentFolder.firstChildFile=currentFile.nextFile;//如果當前檔案的前面沒有檔案,那麼設定當前檔案的父目錄下的第一個檔案為當前檔案的下一個檔案
		if(currentFile.nextFile!=null)
			currentFile.nextFile.frontFile=null;//當前檔案的下一個檔案沒有上一個檔案,因為當前檔案要被刪除了
	}
	else
		currentFile.frontFile.nextFile=currentFile.nextFile;//將當前檔案的上一個檔案和下一個檔案連線起來
	System.out.println("刪除成功!");
	}
	
	void displayFileSystemStructure(FOLDER currentFolder) {//輸出目錄結構
		FILE tempFile;
		if(currentFolder!=null&&currentFolder.canRead==1) {//如果為1,那麼有許可權
			for(int i=0;i<count;i++)
				System.out.print("");
			System.out.println("|-");
			System.out.println("("+currentFolder.name+")");
			if(currentFolder.nextFolder!=null) {
				System.out.println(currentFolder.name+"目錄的同級下一目錄為:"+currentFolder.nextFolder.name);
			}
			int length=15-count*2-currentFolder.name.length();
			for(int i=0;i<length;i++)
				System.out.print("");
			if(count==0)
				System.out.println(currentFolder.canRead+" "+currentFolder.canWrite);
			else
				System.out.println(currentFolder.canRead+" "+currentFolder.canWrite);
			
		}
		else if(currentFolder==null) {
			
			
			count--;
			return;
		}
		count++;
		tempFile=currentFolder.firstChildFile;
		while(tempFile!=null) {
			if(tempFile.canRead==1) {
				for(int i=0;i<count;i++)
					System.out.print("");
				System.out.println("|-");
				System.out.println(tempFile.name);
				int length=20-count*2-tempFile.name.length();
				for(int i=0;i<length;i++)
					System.out.print("");
				if(count==0)
					System.out.println(currentFolder.canRead+" "+currentFolder.canWrite);
				else 
					System.out.println(currentFolder.canRead+" "+currentFolder.canWrite);
			}
			tempFile=tempFile.nextFile;
		}
		displayFileSystemStructure(currentFolder.firstChildFolder);//遍歷子目錄
		displayFileSystemStructure(currentFolder.nextFolder);//遍歷同級目錄
	}
	
	void showFileContent() {//顯示檔案內容
		Scanner in=new Scanner(System.in);
		FILE currentFile=null;
		String name=new String();
		System.out.println("輸入檔名:");
		name=in.nextLine();
		
		currentFile=findCurrentFile(root, name);
		if(currentFile==null) {
			System.out.println("檔案不存在!");
			return;
		}
		if(currentFile.canRead==0) {
			System.out.println("許可權不夠,無法讀取!");
			return;
		}
		System.out.println("檔案內容:"+currentFile.content);
		System.out.println("檔案長度:"+currentFile.content.length());
	}
	
	void changeFileContent() {//更改檔案內容
		Scanner inScanner=new Scanner(System.in);
		FILE currentFile=null;
		String name=new String();
		System.out.println("請輸入檔名:");
		name=inScanner.nextLine();
		inScanner.nextLine();
		currentFile=findCurrentFile(root, name);
		if(currentFile==null) {
			System.out.println("檔案不存在!");
			return;
		}
		if(currentFile.canWrite==0) {
			System.out.println("許可權不夠,不能修改!");
			return;
		}
		System.out.println("請輸入檔案內容:");
		currentFile.content=inScanner.nextLine();
		inScanner.nextLine();
		System.out.println("更改成功!");
		
	}
	
	void changeAllChildPermission(FOLDER currentFolder,int canRead,int canWrite) {//更改子目錄下所有目錄和檔案許可權
		FILE tempFile;
		if(currentFolder!=null) {
			currentFolder.canRead=canRead;
			currentFolder.canWrite=canWrite;
		}
		else if(currentFolder==null)
			return;
		tempFile=currentFolder.firstChildFile;
		while(tempFile!=null) {//遍歷子檔案
			tempFile.canRead=canRead;
			tempFile.canWrite=canWrite;
			tempFile=tempFile.nextFile;
		}
		changeAllChildPermission(currentFolder.firstChildFolder, canRead, canWrite);
		if(currentFolder.firstChildFolder!=null)
			changeAllChildPermission(currentFolder.firstChildFolder.nextFolder, canRead, canWrite);		
	}
	
	void changeFolderPermission() {//更改目錄許可權
		Scanner in=new Scanner(System.in);
		String name=new String();
		
		System.out.println("請輸入要更改許可權的目錄名稱:");
		name=in.nextLine();
		if(name=="root") {
			System.out.println("根目錄不準修改");
			
			return;
		}
		FOLDER currentFolder=null;
		currentFolder=findCurrentFolder(root, name);
		if(currentFolder==null) {
			System.out.println("目錄不存在");
			return;
		}
		System.out.println("輸入目錄許可權(讀和寫):");
		String tempInput=in.nextLine();
		
		currentFolder.canRead=tempInput.charAt(0);
		currentFolder.canWrite=tempInput.charAt(1);
		changeAllChildPermission(currentFolder, currentFolder.canRead, currentFolder.canWrite);//更改當前目錄許可權時,同時更改目錄下所有檔案和目錄許可權
		System.out.println("許可權更改成功!"); 
	}
	
	void changeFilePermission() {//更改檔案許可權
		Scanner in=new Scanner(System.in);
		String name=new String();
		System.out.println("請輸入要更改許可權的的檔名稱:");
		name=in.nextLine();
		FILE currentFile=null;
		currentFile=findCurrentFile(root, name);
		if(currentFile==null) {
			System.out.println("檔案不存在!");
			return;
		}
		System.out.println("輸入檔案許可權(讀和寫):");
		String tempInput=in.nextLine();
		
		currentFile.canRead=tempInput.charAt(0);
		currentFile.canWrite=tempInput.charAt(1);
		System.out.println("許可權更改成功!"); 
		
	}
	
	int fileNameIsDuplication(FILE currentFile,String name) {//判斷新重新命名的檔案是否重名
		FILE tempFile=currentFile.frontFile;
		while(tempFile!=null) {
			if(tempFile.name.equals(name)) {
				System.out.println("檔案重名!");
				return 1;
			}
			tempFile=tempFile.nextFile;
		}
		tempFile=currentFile.nextFile;
		while(tempFile!=null) {
			if(tempFile.name.equals(name)) {
				System.out.println("檔案重名!");
				return 1;
			}
			tempFile=tempFile.nextFile;
		}
		return 0;
	}
	
	int folderNameIsDuplication(FOLDER currentFolder,String name) {//判斷新重新命名的目錄是否重名
		FOLDER tempFolder=currentFolder.frontFolder;
		while(tempFolder!=null) {
			if(tempFolder.name.equals(name)) {
				System.out.println("目錄重名!");
				return 1;
			}
			tempFolder=tempFolder.frontFolder;
		}
		tempFolder=currentFolder.nextFolder;
		while(tempFolder!=null) {
			if(tempFolder.name.equals(name)) {
				System.out.println("目錄重名!");
				return 1;
			}
			tempFolder=tempFolder.nextFolder;
		}
		return 0;
	}
	
	void renameFolder() {//重新命名目錄
		Scanner in=new Scanner(System.in);
		String name=new String();
		System.out.println("請輸入要重新命名的目錄名稱:");
		name=in.nextLine();
		if(name=="root") {
			System.out.println("根目錄不準修改");
			
			return;
		}
		FOLDER currentFolder=findCurrentFolder(root, name);
		if(currentFolder==null) {
			System.out.println("目錄不存在!");
			
			return;
		}
		System.out.println("輸入新目錄名稱:");
		name=in.nextLine();
		
		
		if(folderNameIsDuplication(currentFolder, name)==1)//重名
			return;
		currentFolder.name=name;
		System.out.println("重新命名成功!");
	}
	
	void renameFile() {//重新命名檔案
		Scanner in=new Scanner(System.in);
		String name=new String();
		System.out.println("請輸入要重新命名的檔名稱:");
		name=in.nextLine();
		FILE currentFile=findCurrentFile(root, name);
		if(currentFile==null) {
			System.out.println("檔案不存在!");
			return;
		}
		System.out.println("輸入新名稱:");
		name=in.nextLine();
		
		if(fileNameIsDuplication(currentFile, name)==1)//重名是1,為0則不重名
			return;
		currentFile.name=name;
		System.out.println("重新命名成功!");
		
	}
	
	void menu() {//選單
		Scanner in = new Scanner(System.in);
		int choice;
		System.out.println("**********************");
		System.out.println("1.建立目錄");
		System.out.println("2.刪除目錄");
		System.out.println("3.重新命名目錄");
		System.out.println("4.更改目錄許可權");
		System.out.println("5.建立檔案");
		System.out.println("6.刪除檔案");
		System.out.println("7.重新命名檔案");
		System.out.println("8.顯示檔案內容");
		System.out.println("9.更改檔案內容");
		System.out.println("10.更改檔案許可權");
		System.out.println("0.退出");
		System.out.println("***********************");
		count=0;
		System.out.println("根目錄為:"+root.name);
		System.out.println("目錄結構:");
		
		displayFileSystemStructure(root);
		while(true) {
			System.out.println("請選擇操作命令:");
			choice=in.nextInt();
			
			switch(choice) {
			case 1:
				createFolder();
				break;
			case 2:deleteFoder();
				break;
			case 3:renameFolder();
				break;
			case 4:changeFolderPermission();
				break;
			case 5:createFile();
				break;
			case 6:deleteFile();
				break;
			case 7:renameFile();
				break;
			case 8:showFileContent();
				break;
			case 9:changeFileContent();
				break;
			case 10:changeFilePermission();
				break;
			case 0:return;
			default: break;
			}
		count=0;
		System.out.println("目錄結構:");
		displayFileSystemStructure(root);
		}
		
	}
	
	void initRootFolder() {//初始化根目錄資訊
		root=new FOLDER();
		root.frontFolder=null;
		root.nextFolder=null;
		root.parentFolder=null;
		root.firstChildFile=null;
		root.firstChildFolder=null;
		root.canRead=1;
		root.canWrite=1;
		root.name="root";
	}
	
}
class FOLDER{//目錄結構
	String name=new String();//目錄名
	int canRead;//是否可讀
	int canWrite;//是否可寫
	FOLDER nextFolder;//同級下一目錄
	FOLDER frontFolder;//同級上一目錄
	FOLDER parentFolder;//父目錄
	FOLDER firstChildFolder;//子目錄
	FILE firstChildFile;//子檔案
}
class FILE{
	String name=new String();//檔名
	String content=new String();//檔案內容
	int canRead;
	int canWrite;
	FILE frontFile;//同級目錄上一檔案
	FILE nextFile;//同級目錄下一檔案
	FOLDER parentFolder;//父目錄
}