操作系统实验之文件管理

目录


一、实验目的

通过这次实验,掌握文件系统的用户管理,掌握普通文件、目录文件管理的基本原理。

二、实验内容

1、通过初始化操作建立一个模拟外存空间的虚拟磁盘文件,在该文件中保存目录和文件内容。创建该文件时应创建初始的根目录内容、文件分配表。根目录实为一特殊文件,其开始内容为空,大小为一个块。

2、文件目录项(可以采用FCB格式)应包括类型(目录 or文件)、创建日期、大小、第一个磁盘块块号。

3、显示命令提示符“$”,并根据输入命令完成相应的文件操作:

●MD(创建子目录):创建目录文件,并在父目录文件中增加目录项。

●RD(删除子目录):搜索所要删除的目录是否为空目录,若是则删除。

●MK(创建空文件):创建指定大小的文件(如输入命令 “mk test 2000”,表示创建大小为2000字节的test文件),并在父目录中添加文件名称;还应对FAT表进行适当修改。

●DEL(删除文件):如果所要删除的文件存在,则删除,同时修改父目录内容;还应对FAT表进行适当修改

三、实验思路

 通过实现Node类和文件目录类实现对文件和目录的管理,创建可变长度的数组实现的文件和目录的增删功能,同时运用数据结构链表实现文件和目录的关系。FAT表则是以数组的形式实现,每次创建或删除文件都对数组进行遍历实现对FAT表的修改。

四、主要数据结构

 

文件目录项:记录文件或目录的名称、大小、起始块号、类型、创建时间信息。

文件目录节点:记录某个节点的所有后继节点,实现树状目录结构。

FAT表:使用固定大小的数组来实现,数组的索引表示空闲块号,数组内容表示文件分配的空间。

五、实验流程图

 

 

 

六、实现代码

文件结构:


import java.text.SimpleDateFormat;
import java.util.Date;
//文件目录类
public class file_dir {
	String name;//文件名
	int size; //文件大小:单位KB
	int first_block; //起始块号:第一块块号,从0开始
	char type; //类型,1为文件,2为目录,0为已删除目录项
	String datetime; //日期时间,格式为yyyy-MM-dd HH:mm:ss
	public file_dir() {
		super();
		// TODO Auto-generated constructor stub
		Date day=new Date();    
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
		String str=df.format(day);
		datetime=str;
	}
}
节点:
import java.util.LinkedList;
public class Node {
	file_dir node;
	LinkedList<Node> child;//孩子结点
	public Node(file_dir node, LinkedList<Node> child) {
		super();
		this.node = node;
		this.child = child;
	}
}
//主程序:
package 实验三;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Scanner;
public class file_management {
	public static int SIZE=102400;//虚拟磁盘空间大小,单位:Byte
	public static int used_aera=0;//表示使用过的空间大小
	public static int BLOCKSIZE=1024;//磁盘块大小
	public static int END=-1;//FAT表的结束标志
	public static int m = 3;//命令输入错误允许的次数
//	public static int FREE=0;//FAT表的空闲标志
	public static int[] FAT=new int[100];//FAT表
	public static Node r;//根目录
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		init();
        Scanner scan=new Scanner(System.in);
        while(true) {
        	System.out.println("**************************************");
        	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----查看FAT表");
        	System.out.println("7----退出");
        	int i = scan.nextInt();
        	scan.nextLine();
        	switch (i) {
			case 1: {
				System.out.println("请输入命令:");
				System.out.print("$");
	        	String str=scan.nextLine();//以Enter为行结束符
	        	String[] cmd=str.split(" ");
	        	md(cmd[1]);
	        	break;
			}case 2: {
				System.out.println("请输入命令:");
				System.out.print("$");
	        	String str=scan.nextLine();//以Enter为行结束符
	        	String[] cmd=str.split(" ");
	        	rd(cmd[1]);
	        	break;
			}
			case 3: {
				System.out.println("请输入命令:");
				System.out.print("$");
	        	String str=scan.nextLine();//以Enter为行结束符
	        	String[] cmd=str.split(" ");
	        	int s=Integer.parseInt(cmd[2]);
				mk(cmd[1], s);
				break;
			}
			case 4: {
				System.out.println("请输入命令:");
				System.out.print("$");
	        	String str=scan.nextLine();//以Enter为行结束符
	        	String[] cmd=str.split(" ");
	        	del(cmd[1]);
				break;
			}
			case 5: {
				System.out.println("请输入命令:");
				System.out.print("$");
	        	String str=scan.nextLine();//以Enter为行结束符
	        	String[] cmd=str.split(" ");
	        	ls(cmd[1]);
				break;
			}
			case 6: {
	        	fat();
	        	break;
			}case 7: {
				System.out.println("退出成功!");
	        	return;	
			}
			default:
				if(m>=0) {
				System.out.println("系统不存在此命令!");
				System.out.println("请重新输入");
				m--;
				}else {
					break;
				}
			}
        }
    }
	//创建子目录:md 目录名称
	public static void md(String path) {
		String[] result=path.split("\\\\");
		Node f=find_father(result);
		file_dir n=new file_dir();
		n.name=result[result.length-1];
		n.type=2;
		n.size=1;
		f.child.add(new Node(n, new LinkedList<Node>()));
		System.out.println("创建完成!");
	}
	//删除子目录:仅能删除空目录,不空返回删除失败 rd 目录名称
	public static void rd(String path) {
		String[] result=path.split("\\\\");
		Node f=find_father(result);
		Node p = null;
		for (int i = 0; i < f.child.size(); i++) {			
			if (f.child.get(i).node.name.equals(result[result.length-1])) {
				p=f.child.get(i);
			}
		}
		if (p.child.size()==0) {
			f.child.remove(p);
			System.out.println("删除成功!");
		}
		else {
			System.out.println("该目录不为空,删除失败!");
		}
	}
	//寻找父目录
	public static Node find_father(String path[]) {
		Node p=r;
		for(int i=1;i<path.length-1;i++) {
			for(int j=0;j<p.child.size();j++) {
				if (p.child.get(j).node.name.equals(path[i])) {
					p=p.child.get(j);
					break;
				}
			}
		}
		return p;
	}
	//创建空文件:创建指定大小的文件,并在父目录中添加文件名称,对FAT表进行适当修改 mk 文件名称 文件大小
	public static void mk(String path,int size) {
		//磁盘空间不足,返回提示语句,退出
		if (SIZE-used_aera-size*1024<=0) {
			System.out.println("空间不足!");
			return;
		}
		//为文件分配磁盘空间,修改FAT表
		String[] result=path.split("\\\\");
		file_dir n=new file_dir();
		n.name=result[result.length-1];
		n.type=1;
		n.size=size;
		for (int i = 0; i < FAT.length; i++) {
			//遍历寻找第一块空闲空间
			if (FAT[i]==0) {
				n.first_block=i;
				int b=1;
				int index=i;
				//接着寻找size-1块空闲空间,并记录该文件的链接情况
				for (int j = i+1; j < FAT.length; j++) {
					if (FAT[j]==0) {
						FAT[index]=j;
						index=j;
						b++;
					}
					if (b==size) {
						FAT[j]=END;
						break;
					}
				}
				break;
			}
		}
		Node f=find_father(result);
		f.child.add(new Node(n, null));
		used_aera+=(size*1024);
		System.out.println("创建完成!");
	}
	//删除文件:如果所要删除的文件存在,则删除,同时修改父目录内容,对FAT表进行适当修改 del 文件名称
	public static void del(String path) {
		String[] result=path.split("\\\\");
		Node f=find_father(result);
		Node p = null;
		for (int i = 0; i < f.child.size(); i++) {
			if (f.child.get(i).node.name.equals(result[result.length-1])) {
				p=f.child.get(i);
			}
		}
		if(p==null) {
			System.out.println("文件不存在!");
		}
		else {
			used_aera-=p.node.size*1024;
			f.child.remove(p);
			//修改FAT表
			int index=p.node.first_block;
			while(true) {
				int temp=FAT[index];
				FAT[index]=0;
				if(temp==-1) {
					break;
				}
				index=temp;
			}
			System.out.println("删除成功!");
		}
	}
	//列出目录:若查询非目录而是文件,返回提示语句 ls 目录名称
	public static void ls(String path) {
		String[] result=path.split("\\\\");
		//若查询根目录
		if (result.length==1&&result[0].equals("root")) {
			for (int i = 0; i < r.child.size(); i++) {
				System.out.print(r.child.get(i).node.name+" ");
			}
			System.out.println();
			return;
		}
		Node f=find_father(result);
		Node p = null;
		for (int i = 0; i < f.child.size(); i++) {
			if (f.child.get(i).node.name.equals(result[result.length-1])) {
				p=f.child.get(i);
			}
		}
		if (p.node.type==1) {
			System.out.println("该路径不是目录!");
		}
		else {
			for (int i = 0; i < p.child.size(); i++) {
			System.out.print(p.child.get(i).node.name+" ");
		    }
			System.out.println();
		}
	}
	//查看FAT文件分配表
	public static void fat() {
		for (int i = 0; i < FAT.length; i++) {
			if (FAT[i]==0) {
				System.out.print(i+":0 ");
			}
			else {
				System.out.print(i+":"+FAT[i]+" ");
			}
			if (i%10==0) {
				System.out.println();
			}
			}
		System.out.println();
	}
	//初始化:创建该文件时应创建初始的根目录内容、文件分配表FAT表。
	public static void init() {
		//根目录:实为一特殊文件,其开始内容为空,大小为一个块。
		file_dir root=new file_dir();
		root.size=1;
		root.name="root";
		root.type=2;
		r=new Node(root,new LinkedList<Node>());
		//FAT表初始化:使每一块均处于空闲状态
		for (int i = 0; i < FAT.length; i++) {
			FAT[i]=0;
		}
	}
}

七、运行结果

**************************************
请选择你要进行的操作:
1----创建目录
2----删除目录
3----创建文件
4----删除文件
5----查看文件或目录
6----查看FAT表
7----退出
1
请输入命令:
$md root\dir1
创建完成!
**************************************
请选择你要进行的操作:
1----创建目录
2----删除目录
3----创建文件
4----删除文件
5----查看文件或目录
6----查看FAT表
7----退出
1
请输入命令:
$md root\dir2
创建完成!
**************************************
请选择你要进行的操作:
1----创建目录
2----删除目录
3----创建文件
4----删除文件
5----查看文件或目录
6----查看FAT表
7----退出
1
请输入命令:
$md root\dir3
创建完成!
**************************************
请选择你要进行的操作:
1----创建目录
2----删除目录
3----创建文件
4----删除文件
5----查看文件或目录
6----查看FAT表
7----退出
3
请输入命令:
$mk root\dir1\file1 30
创建完成!
**************************************
请选择你要进行的操作:
1----创建目录
2----删除目录
3----创建文件
4----删除文件
5----查看文件或目录
6----查看FAT表
7----退出
3
请输入命令:
$mk root\dir2\file2 40
创建完成!
**************************************
请选择你要进行的操作:
1----创建目录
2----删除目录
3----创建文件
4----删除文件
5----查看文件或目录
6----查看FAT表
7----退出
3
请输入命令:
$mk root\dir3\file3 40
空间不足!
**************************************
请选择你要进行的操作:
1----创建目录
2----删除目录
3----创建文件
4----删除文件
5----查看文件或目录
6----查看FAT表
7----退出
3
请输入命令:
$mk root\dir3\file3 20
创建完成!
**************************************
请选择你要进行的操作:
1----创建目录
2----删除目录
3----创建文件
4----删除文件
5----查看文件或目录
6----查看FAT表
7----退出
5
请输入命令:
$ls root
dir1 dir2 dir3 
**************************************
请选择你要进行的操作:
1----创建目录
2----删除目录
3----创建文件
4----删除文件
5----查看文件或目录
6----查看FAT表
7----退出
5
请输入命令:
$ls root\dir1
file1 
**************************************
请选择你要进行的操作:
1----创建目录
2----删除目录
3----创建文件
4----删除文件
5----查看文件或目录
6----查看FAT表
7----退出
6
0:1 
1:2 2:3 3:4 4:5 5:6 6:7 7:8 8:9 9:10 10:11 
11:12 12:13 13:14 14:15 15:16 16:17 17:18 18:19 19:20 20:21 
21:22 22:23 23:24 24:25 25:26 26:27 27:28 28:29 29:-1 30:31 
31:32 32:33 33:34 34:35 35:36 36:37 37:38 38:39 39:40 40:41 
41:42 42:43 43:44 44:45 45:46 46:47 47:48 48:49 49:50 50:51 
51:52 52:53 53:54 54:55 55:56 56:57 57:58 58:59 59:60 60:61 
61:62 62:63 63:64 64:65 65:66 66:67 67:68 68:69 69:-1 70:71 
71:72 72:73 73:74 74:75 75:76 76:77 77:78 78:79 79:80 80:81 
81:82 82:83 83:84 84:85 85:86 86:87 87:88 88:89 89:-1 90:0 
91:0 92:0 93:0 94:0 95:0 96:0 97:0 98:0 99:0 
**************************************
请选择你要进行的操作:
1----创建目录
2----删除目录
3----创建文件
4----删除文件
5----查看文件或目录
6----查看FAT表
7----退出
2
请输入命令:
$rd root\dir3
该目录不为空,删除失败!
**************************************
请选择你要进行的操作:
1----创建目录
2----删除目录
3----创建文件
4----删除文件
5----查看文件或目录
6----查看FAT表
7----退出
4
请输入命令:
$del root\dir3\file3
删除成功!
**************************************
请选择你要进行的操作:
1----创建目录
2----删除目录
3----创建文件
4----删除文件
5----查看文件或目录
6----查看FAT表
7----退出
2
请输入命令:
$rd root\dir3
删除成功!
**************************************
请选择你要进行的操作:
1----创建目录
2----删除目录
3----创建文件
4----删除文件
5----查看文件或目录
6----查看FAT表
7----退出
5
请输入命令:
$ls root
dir1 dir2 
**************************************
请选择你要进行的操作:
1----创建目录
2----删除目录
3----创建文件
4----删除文件
5----查看文件或目录
6----查看FAT表
7----退出
6
0:1 
1:2 2:3 3:4 4:5 5:6 6:7 7:8 8:9 9:10 10:11 
11:12 12:13 13:14 14:15 15:16 16:17 17:18 18:19 19:20 20:21 
21:22 22:23 23:24 24:25 25:26 26:27 27:28 28:29 29:-1 30:31 
31:32 32:33 33:34 34:35 35:36 36:37 37:38 38:39 39:40 40:41 
41:42 42:43 43:44 44:45 45:46 46:47 47:48 48:49 49:50 50:51 
51:52 52:53 53:54 54:55 55:56 56:57 57:58 58:59 59:60 60:61 
61:62 62:63 63:64 64:65 65:66 66:67 67:68 68:69 69:-1 70:0 
71:0 72:0 73:0 74:0 75:0 76:0 77:0 78:0 79:0 80:0 
81:0 82:0 83:0 84:0 85:0 86:0 87:0 88:0 89:0 90:0 
91:0 92:0 93:0 94:0 95:0 96:0 97:0 98:0 99:0 
**************************************
请选择你要进行的操作:
1----创建目录
2----删除目录
3----创建文件
4----删除文件
5----查看文件或目录
6----查看FAT表
7----退出
7
退出成功!

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2023年12月11日
下一篇 2023年12月11日

相关推荐