广工操作系统课设--多用户多级目录的文件系统

广东工业大学课程设计任务书

一、课程设计的内容

本课程设计要求设计一个模拟的多用户多级目录的文件系统。通过具体的文件存储空间的管理、文件的物理结构、目录结构和文件操作的实现,加深对文件系统内部功能和实现过程的理解。

二、课程设计的要求与数据

1. 在内存中开辟一个虚拟磁盘空间作为文件存储器,在其上实现一个多用户多目录的文件系统。

2. 文件物理结构可采用显式链接或其他方法。

3. 磁盘空闲空间的管理可选择位示图或其他方法。如果采用位示图来管理文件存储空间,并采用显式链接分配方式,则可以将位示图合并到FAT中。

4. 文件目录结构采用多用户多级目录结构,每个目录项包含文件名、物理地址、长度等信息,还可以通过目录项实现对文件的读和写的保护。目录组织方式可以不使用索引结点的方式,但使用索引结点,则难度系数为1.2。

5. 设计一个较实用的用户界面,方便用户使用。要求提供以下相关文件操作:

(1)具有login (用户登录)

(2)系统初始化(建文件卷、提供登录模块)

(3)文件的创建: create

扫描二维码关注公众号,回复: 14588872 查看本文章

(4)文件的打开:open

(5)文件的读:read

(6)文件的写:write

(7)文件关闭:close

(8)删除文件:delete

(9)创建目录(建立子目录):mkdir

(10)改变当前目录:cd

(11)列出文件目录:dir

(12)退出:logout

6. 系统必须可实际演示,选用程序设计语言:C++、C等。

三、课程设计应完成的工作

1.充分理解设计的任务,完成设计的基本要求。然后根据自己的基础和能力选择不同难度的算法和实现方式,以取得更高的分数。

\2. 独立独立完成系统的分析、设计、编码、测试工作。

3.完成设计报告的撰写。

4.以光盘(以班为单位刻录)方式提交已调试通过的完整的相关源程序和能够运行的执行文件;提交“课程设计报告”的书面和电子两种版本。

四、课程设计进程安排

序号 设计各阶段内容 地点 起止日期
1 查阅资料、分析题目、概要设计 分散 周一
2 详细设计、编码 分散 周二
3 调试 实验室 周三
4 撰写设计报告 分散 周四
5 运行、验收 实验室 周五

五、应收集的资料及主要参考文献

[1] 计算机操作系统, 汤小丹等 ,西安电子科技大学出版社

[2] 操作系统实验指导书,傅秀芬,广东工业大学(自编)

[3] 计算机操作系统教程 ( 第二版 ), 张尧学、 史美林,清华大学出版社

[4] 现代操作系统,A.S.Tanenbaum 著,陈向群等译机械工业出版社

一、 设计思想说明

1.1 设计环境

a) 编程语言:Java

b) 开发环境:IntelliJ IDEA 2021.1.1

c) 操作系统:windows 11

1.2 设计思想

1.2.1 整体思想

本课设要求开发一个模拟的多用户多级目录的文件系统,要求实现多用户注册、登录与退出,文件的增删改查打开关闭以及目录的创建切换与显示。本人开发过程中基于Linux系统的文件目录操作思想以及输出格式进行开发,文件的物理结构采用显示链接法,磁盘空间的管理选择位示图,同时将位示图合并到FAT表中,目录项增加了索引结点的方式进行封装,大量节省目录的空间,加快访问速率。在100%完成任务书要求之余,我还基于linux文件权限简化设计了涉及文件创建者及其他用户的文件权限保护,并且,系统界面针对不同的文件格式可显示不同的颜色进行明显区分。整个系统分为四大模块的开发:用户管理模块,文件操作模块,目录操作模块,数据存储模块。

1.2.2 用户管理模块

用户管理包括用户注册、登录以及退出功能。

(1) 系统设置userMap<String username , User user>充当用户数据库,在磁盘上分配以磁盘块专门存放用户数据,系统运行之后就读入内存。

(2) 登录(login)进行用户名密码校验,登录后可显示用户上一次登录时间(这一点是仿造linux进行的添加),登录后默认进入每个用户的同名专属文件夹,设置内存curUser为当前用户。用户可以使用cd命令切换到其他有权限目录。

(3) 注册时进行用户名重名检测,将用户名、密码添加到用户数据库,注册成功后为用户添加一个同名用户文件夹,设置权限为(rwx—)只允许用户自己访问,同时加入根目录下。

(4) 用户退出时系统会自动进行数据持久化保存,保证数据不丢失。

Login、register操作只可以在未登录状态下进行,而logout操作只允许在登录状态下进行。

1.2.3 文件操作模块

文件操作包括创建(create)文件、打开(open)文件、关闭(close)文件、显示打开的文件(show_open)、读取(read)文件内容、覆盖写入或追加写入(write)文件、删除(delete)文件、文件重命名(rename)等操作。本系统的所有文件操作实现了跨目录操作,只要有权限以及文件存在便可以进行操作,而不是只能操作当前目录文件。

(1) create:用户输入create + 文件名,系统进行文件名判空和重名检测 如无重名文件即进行创建。创建过程包括创建文件索引结点和文件控制块FCB,文件大小为空文件,将FCB存入磁盘,修改父目录的文件项,加入到父目录的儿子集合。

(2) open: 用于打开文件,用于在对文件进行操作前需要先打开文件,这样可以方便操作系统分配资源使用权比如外设的管理。打开文件包括解析文件路径是否存在,解析是否是普通文件,判断用户权限,判断是否重复打开,然后封装为openFile加入到openFileList中。系统可选择打开多个文件。

(3) close:用于关闭文件,只有关闭文件才可以释放资源使用权,别的进程才可以进行使用该资源,用于在进行logout操作之前需要先确保关闭了打开的文件,否则无法正常退出。关闭过程包括:解析文件路径是否存在,解析是否是普通文件,判断是否在openFileList中。

(4) show_open:用于用户查看打开了什么文件,方便用于进行正常关闭操作。

(5) read:读取文件内容并显示出来给用户看。读取包括解析文件路径是否存在,解析是否是普通文件,判断用户权限,判断是否打开,必须先打开才能进行读取,随后进从文件的FCB中读取到第一块存放的位置,然后使用FAT表到磁盘进行一一读取。

(6) write:用于用户对文件写入内容。写入有两种模式:覆盖写与追加写,新文件默认是覆盖写。写入过程包括:解析文件路径是否存在,解析是否是普通文件,判断用户权限,判断是否打开,必须先打开才能进行写入。如果是覆盖写入,则先清除文件的旧FAT表分配关系,再进行分配,将用户输入内容分块写入磁盘,修改FAT表及位示图,修改父目录文件项及递归修改父目录的文件大小;如果是追加写入,则找到FAT中指定的最后一块,在此基础上继续分配。

(7) delete:删除文件,允许用户删除文件及空目录。删除过程包括:解析文件路径是否存在,解析是否有权限,删除文件需要有rw权限,删除文件夹还需要执行权限。判断是否打开,如果打开则要先关闭才能删除,随后修改父目录大小及文件项,修改FAT表及位示图

(8) rename:文件重命名操作。过程包括解析文件路径是否存在,解析是否是普通文件,判断用户权限,判断是否打开,判断文件名是否重复,随后修改文件的FCB中的名称字段。

1.2.4 目录操作模块

目录操作包括显示(dir)目录文件项详细信息、创建(mkdir)目录、切换(cd)目录、解析(pathReslove)路径、更新目录(updateSize)大小、显示目录(ls)文件名、显示(pwd)全路径、显示当前(showPath)目录、显示位示图(bitmap)。本系统的所有目录操作实现了全路径操作,只要有权限及文件存在即可进行操作。

(1) dir: dir操作与linux的ll指令实现效果基本一致,可以显示目录下文件的文件类型、目录权限、创建者、文件大小、修改时间、文件名。例如:drwx— 4 root 32 2022.10.1 a.txt 同时,对于不同后缀文件格式,也仿照linux进行不同颜色显示,白色表示普通文件、绿色表示可执行文件、红色表示压缩文件、蓝色表示目录文件。

(2) mkdir:默认在当前目录下创建新目录项。创建过程包括目录名判空,目录名判断重复,创建索引结点,创建FCB,存入磁盘,修改父目录文件项,加入到父目录儿子集合。

(3) cd:切换目录操作,可切换到用户指定的有权限目录。cd … cd …/表示切换到上级目录。切换目录包括解析目录路径,判空,判断是否是目录文件,判断权限,如果都正常即切换目录并更新内存指定的当前目录。

(4) pathReslove:用于所有需要路径解析的功能,解析指定路径是否存在,存在则返回文件或目录的FCB。路径解析包括判断是否是当前目录,在指定目录寻找,或从根目录往下逐层寻找。

(5) updateSize:作用于文件大小有变化,逐级往上递归修改父目录的文件大小。其过程包括逐级往上遍历,判断增加还是减少,直到遍历到根目录。

(6) ls:用于显示当前目录的文件名。过程包括获得内存指定的当前目录FCB,遍历输出儿子集合目录项。

(7) pwd:模仿linux操作,指令输入时不直接显示当前相对于根目录的全路径,而是显示当前目录名而已,使用pwd操作才可以获得全路径。过程包括逐层往上遍历直到根目录。

(8) showPath:用于输入命令时显示当前目录及当前登录的用户。

(9) bitmap:用于显示磁盘的使用情况,由于位示图嵌入FAT表,因此遍历FAT表可得到所有磁盘的使用情况。

1.2.5 数据存储模块

数据存储模块即磁盘操作,本系统实现了数据存储功能,用户所有的操作都是永久性的,当用户logout后,系统就会自动将用户数据和磁盘数据序列化存储到“system.data”中包括系统磁盘和FAT表初始化(init),从虚拟存储文件中加载磁盘数据(loadData),存储数据到虚拟磁盘文件(saveData),释放文件的磁盘空间(freeFile),写入数据到磁盘(writeToDisk),从磁盘中寻找空闲块(find_empty)。

(1) init:当系统找不到序列化的虚拟磁盘文件,就会进行初始化操作。初始化包括初始化磁盘数据,FCB集合数据,根目录数据,FAT表,内存数据,用户集合数据。

(2) loadData:当存储路径文件存在时,系统通过字节流加载磁盘数据,同时将磁盘中的用户集合数据、根目录、当前用户、当前目录、FAT表读入内存。

(3) saveData:当用户退出系统时,系统自动将内存数据持久化到磁盘中,再将磁盘存储到虚拟磁盘文件中。

(4) freeFile:清除文件占有的磁盘空间,修改FAT表,递归修改父目录文件大小,清空索引结点

(5) writeToDisk:将用户输入的内容存入磁盘持久化。过程包括:判断是否有足够的磁盘空间,遍历FAT表寻找空闲块,将文件内容分块存储进去,随后返回第一个块号

(6) find_empty:用于存储内容时寻找空闲块块号返回块号。

二、 系统结构

系统结构分为四层,用户层,文件层,内存层,磁盘层。如图显示出根目录下存在多个与用户名同名的文件夹,使用双亲孩子节点法进行联系,文件采用索引结点方式存储FCB详细信息,文件内容存储在磁盘中,需要通过索引结点找到第一个物理块号,再从FAT表中查找所有的块号,从而读取出文件内容。内存中实时显示当前用户与当前目录。

img

三、 数据结构的说明

3.1 User

用户数据结构分为用户名、密码、上次登录时间,用户数据使用userMap充当数据库进行持久化。

public class User implements Serializable {
    
    
    private String userName; //用户名
    private String password; //密码
    private Date lastLoginTime; //上次登录的时间
}

3.2 磁盘数据结构

磁盘整体内存为2MB,共分为256个磁盘块,每一物理块可存储8B的数据。

3.2.1 Block

public class Block implements Serializable {
    
    
    private int id; //块号
    private int blockSize; //块大小
    private String content; //块内容
}

3.2.2 Disk

磁盘有专门空间用于存储FCB集合、用户集合、文件分配表FAT,磁盘使用单例模式,保证只有一个磁盘对象,数据不发生冲突。

public class Disk implements Serializable {
    
    
    private static Disk INSTANCE;
    private Block[] disk; //磁盘
    private List<FCB> fcbList; //存储在磁盘上的FCB集合
    private Map<String, User> userMap; //存储在磁盘上的用户集合
    private FAT[] fat;//文件分配表
}

3.3 树形目录数据结构

3.3.1 树形结构

本系统的文件树形结构如下所示

img

系统采用树形结构进行目录组织,根目录是所有目录及文件的根,根目录下每个用户有自己的同名文件夹,用户也可以在根目录下进行创建文件,与其他用户实现文件共享。

3.3.2 FCB

每个文件(普通文件和目录)都有文件控制块FCB,凭借FCB才可以形成树形文件目录。本系统的FCB除了文件名文件类型以外的大部分内容都由索引结点进行封装,加速读取速率。每个FCB有父节点和孩子集合,采用双亲孩子表示法进行树结构的组织。

public class FCB implements Serializable {
    
    
    private String fileName; //文件名
    private Character type; //文件类型 分为目录D 普通文件N
    private IndexNode indexNode; //索引结点
    private FCB father; //父节点
    private List<FCB> children; //孩子集合
}

3.3.3 IndexNode

文件的索引结点存放文件权限,文件大小,存放在的物理块首地址,文件项数(如果是目录才有效,文件为0)以及文件创建者和修改时间。

文件权限仿造linux,同时做了简化,这里用户可以设置文件对自己(创建者)的权限,以及其他用户的权限。权限包括读(r=4)写(w=2)和执行(x=1)。

public class IndexNode implements Serializable {
    
    
    private String permission; //文件访问权限 6位 前三位创建者 后三位其他用户 rwx---
    private int size; //文件大小
    private int first_block; //文件首地址(第一个盘块号)
    private int fcbNum; //文件项个数 如果是普通文件为0 目录看其下有多少个
    private String creator; //创建者
    private Date updateTime; //文件修改时间
}

3.4 FAT数据结构

FAT是文件分配表,用于记录文件的分配情况,同时为节省空间,直接将位示图合并进FAT表中,FAT表只有256项,与磁盘物理块一一对应,可显示磁盘每一块的分配情况。

public class FAT implements Serializable {
    
    
    private int bitmap; //位示图 0表示空闲 1表示占用
    private int id; //当前盘块号
    private int nextId; //指向下一盘块号
}

3.5 内存数据结构

内存中常驻FAT表,当前目录FCB,根目录FCB,用户集合,以及打开的文件集合,本系统实现了文件多开,通过设置openFileList记录每一个打开的文件,还可以防止文件多开以及防止退出文件未保存。

3.5.1 Memory

public class Memory implements Serializable {
    
    
    private static Memory INSTANCE;
    private Map<String, User> userMap; //存储在磁盘上的用户集合 从磁盘读取
    private User curUser; //当前登录用户
    private FCB curDir; //当前目录
    private FCB rootDir;  //根目录常驻内存 根目录可以引出整个文件目录 从磁盘读取
    private FAT[] fat;//文件分配表 从磁盘读取
    private List<OpenFile> openFileList; //打开的文件集合
    private int empty_blockNum; //空闲盘块数 从磁盘读取
}

3.5.2 OpenFile

public class OpenFile implements Serializable {
    
    
    private FCB fcb; //文件控制块
    private String filePath; //文件全路径
}

四、 算法流程图

4.1 系统流程图

img

4.2 核心算法流程图

4.2.1 pathReslove

pathReslove算法是本系统最基础最核心的算法,是实现跨目录文件目录操作的核心。

判断在根目录还是当前目录下寻找。

img

4.2.2 Open

\1. 解析文件路径

\2. 判断是否是普通文件

\3. 判断权限

\4. 判断是否打开

\5. 加入打开文件集合

img

4.2.3 Read

\1. 解析文件路径

\2. 判断是否是普通文件

\3. 判断权限

\4. 判断是否打开

\5. 找到索引结点

\6. 按照FAT表读取磁盘内容

img

4.2.4 Write

\1. 解析文件路径

\2. 判断是否是普通文件

\3. 判断权限

\4. 判断是否打开

\5. 判断是否是新文件

\6. 选择写入模式(覆盖/追加)

img

4.2.5 Delete

\1. 解析文件路径

\2. 判断是否存在

\3. 判断权限(文件rw 目录rwx)

\4. 判断是否打开 打开则需要关闭

\5. 判断是否是非空目录

\6. 释放磁盘空间

\7. 修改FAT表

\8. 递归修改父目录FCB

img

五、 主要函数列表

函数原型 功能 入口、出口参数说明
Boolean login (String userName, String password) 登录 userName 用户名、password 密码
Boolean register (String userName, String password) 注册 userName 用户名、password 密码
Boolean logout () 注销
Boolean create(String fileName, String permission) 创建文件 fileName 文件名称、permission 权限
Boolean open(String filePath) 打开文件 filePath 文件路径
void show_open() 显示打开的文件
Boolean read(String filePath) 读取文件 filePath 文件路径
Boolean write(String filePath) 写入文件 filePath 文件路径
Boolean close(String filePath) 关闭文件 filePath 文件路径
Boolean delete(String filePath) 删除文件 filePath 文件路径
int checkPermission(FCB fcb) 查看当前用户对文件的权限 fcb 文件FCB 返回值:读r=4 写w=2 执行x=1
Boolean rename(String filePath,String newName) 文件重命名 filePath 文件路径 newName 新名字
Boolean freeFile(FCB fcb) 释放文件磁盘空间 fcb 文件FCB
writeToDisk(String content) 文件内容写入磁盘 content 文件内容 返回值:第一块的磁盘号
int find_empty() 寻找空闲块 返回值:int 块号
void dir() 显示当前目录的文件项的详细信息
Boolean mkdir(String dirName,String permission) 创建目录 dirName 目录名 permission 权限
Boolean cd(String dirName) 切换目录 dirName 目录名
FCB pathResolve(String path) 功能函数:用于解析文件路径 存在则返回文件FCB
void updateSize(FCB fcb,Boolean isAdd,int new_add) 递归修改父目录大小 fcb 文件FCB isAdd 是否是添加操作
void ls() 简要显示当前目录文件名
String pwd(FCB fcb) 显示当前全目录路径 FCB fcb
void showPath() 控制台命令框显示当前路径
void bitmap() 显示位示图
void init() 第一次运行系统进行初始化磁盘与FAT表等
Boolean loadData(String dataPath); 加载数据进磁盘 dataPath 数据路径
Boolean saveData(String savePath); 保存系统运行数据 savePath 保存路径

六、 测试与分析

6.1 登录注册

6.1.1 login

提前注册了用户名:zjh,密码:zjh的用户,登录成功会显示上次登录的时间

img

6.1.2 register

img

注册完首次登录,上次登录时间为null

6.2 目录操作

6.2.1 Dir/ll/ls

显示文件目录项的具体信息,会根据不同类型文件进行文件区分。白色:普通文件、蓝色:目录文件、红色:压缩文件、绿色:可执行文件。

Ls可以简略的显示文件名

img

6.2.2 Mkdir

测试:在本目录创建一个全新为rwx—,命名为“hello”的目录

img

6.2.3 Pwd

显示当前目录全路径

img

6.2.4 Cd

切换到指定目录 支持cd …切换回上一级 支持输入全路径快速切换。提前在根目录下设置一个公有的/aaa/bbb/ccc目录。

测试cd …操作 可以一直回退直到根目录

img

可以进入当前目录下有权限目录

img

全路径切换

img

6.3 文件操作

6.3.1 Create

img

6.3.2 Open

可以打开有权限文件

img

6.3.3 Show_open

img

6.3.4 Write Read

打开才可写入 写入空文件默认覆盖写

img

追加写

img

覆盖写

img

6.3.5 Close

退出必须关闭文件

img

6.3.6 Rename

重名检测

img

6.4 其他操作

6.4.1 Help

显示所有的指令用于提示用户

img

6.4.2 Bitmap

显示磁盘分配情况 16*16 1表示被分配 0表示空闲

img

分配

一个块8B,新增大小9B的文件,新增两块

img

回收大小为10B的file.txt,可以看到原来中间的2块1变为空闲0

img

img

七、 用户使用说明

\1. 如项目文件夹下无system.data文件,则需要进行系统初始化操作

\2. 登录后才可以进入系统

\3. 无法访问别的用户的文件

\4. 必须使用logout退出才会保存本次登录后的所有操作结果

\5. 可以使用以下指令进行操作

img

八、 附录

8.1 项目工程分包情况

imgimg

img

8.2 项目文件夹

img

猜你喜欢

转载自blog.csdn.net/weixin_51712663/article/details/125610789