基于Java开发的(控制台)模拟的多用户多级目录的文件系统

多级文件系统

1 设计目的

为了加深对文件系统内部功能和实现过程的理解,设计一个模拟的多用户多级目录的文件系统,并实现具体的文件物理结构、目录结构以及较为完善的文件操作命令集。

2 设计内容

2.1系统操作

操作命令风格:本文件系统的操作命令风格将采用windows系统的文件操作命令风格,操作命令区分大小写,并能在用户错误地执行某些操作之后给出及时反馈,提供良好的交互体验。

具体的操作:本文件系统将实现以下功能操作:

2.2文件物理结构

本文件系统的文件物理结构将采用顺序结构,即将文件记录存储在一块连续的磁盘空间中。相应地,磁盘空间的分配也采用连续分配的方式。

2.3文件目录结构

本文件系统的文件目录结构将采用树形目录结构。树形目录结构的优点是可以更方便有效地管理用户的文件,特别是在多用户系统且用户的文件数量较多的情境中。树形目录结构也是目前最为流行的文件目录结构之一,比较符合大多数人的使用习惯。

2.4磁盘空间管理

本文件系统的磁盘空间管理采用位示图来进行管理,用户可以使用show命令来显示磁盘空间位示图以查看当前系统的磁盘空间使用情况。

2.5额外功能

本文件系统提供查看系统操作命令集的功能,用户可以使用help命令来查看本系统已实现的功能,优化用户的使用体验。

另外,本文件系统还提供了将创建的文件保存到电脑本地的功能,以便用户下次使用本系统时能查看自己所创建的文件。2.6编程语言和环境

本文件系统的编程语言采用Java语言,运行环境为JDK 1.8版本及以上。

3 设计步骤

3.1需求分析

3.1.1功能需求

本文件系统的功能模块将细分为三个模块:用户管理模块、文件管理模块、系统管理模块。各个模块的功能需求如表3.1~表3.3所示。

**表 3. SEQ 表 _ ARABIC \s 1 1 用户管理模块功能需求_

名称详细描述
用户注册用户使用register命令注册一个系统用户,并要求输入用户名和密码
用户登录用户使用login命令进行登录,需要输入用户名和密码进行身份校验
用户注销用户使用logout命令注销当前已登录的用户

表 3.2 文件管理模块功能需求

名称详细描述
创建目录用户使用mkdir命令创建一个文件目录,文件目录名不能和当前目录下的文件或文件目录重名,并且不区分大小写
列出文件用户使用dir命令列出当前目录下的所有文件的详细信息,支持使用路径名
切换目录用户使用cd命令切换到目标目录,路径名使用windows系统的风格
创建文件用户使用create命令创建一个文件,文件名不能和当前目录下的文件或文件目录重名,并且不区分大小写
打开文件用户使用open命令打开一个文件,支持使用路径名
读取文件用户使用read命令读取一个已打开的文件,可向后读取和向前读取
写入文件用户使用write命令向一个已打开的文件写入记录
关闭文件用户使用close命令关闭一个已打开的文件
删除文件用户使用delete命令删除一个存在的文件或文件目录,支持使用路径名
重命名文件用户使用rename命令对一个文件或文件目录进行重命名,新的名称不能和当前目录下的文件或文件目录重名,并且不区分大小写

表 3.3 系统管理模块功能需求

名称详细描述
显示帮助用户使用help命令查看当前系统支持的操作命令以及使用方法
显示磁盘位示图用户使用show命令查看当前磁盘空间的位示图和其他信息
退出系统用户使用exit命令退出文件系统,系统在退出前会保存用户信息、文件信息和磁盘空间信息
3.1.2性能需求

本文件系统具有较高的响应比,在文件信息不是特别多的时候能够做到0延迟响应。并且本文件系统运行所需的内存空间比较小,保存文件的大小与文件信息的多少成正比。

3.1.3交互需求

用户与本文件系统的交互在控制台中进行,并且可以方便地查看系统操作命令,降低了用户的学习使用成本。

本文件系统具有良好的信息展示功能,包括文件信息展示、文件内容展示、操作命令展示、位示图展示,使用户可以及时地获取自己所需要的信息。

本文件系统具有友好的错误信息反馈。在用户想要执行一项不被允许的操作时(如打开不存在的文件)能够给予用户正确、简洁的引导式的错误反馈。

3.2概要设计

3.2.1设计思想

本文件系统在设计上采用模块化的思想,将服务类型一致的功能划分到同一个模块,使项目整体上比较清晰。并且每个模块都提供对外调用的接口,这样就能让其他模块在需要的时候调用本模块的某些功能,实现复用。

3.2.2模块设计

本文件系统分为用户管理模块、文件管理模块和系统管理模块三个大模块。其中各个模块细分如下:

  • 用户管理模块:负责提供用户注册、用户登录、用户注销三个功能。
  • 文件管理模块:文件管理模块还可分为文件模块、文件目录模块以及磁盘模块三个小模块。其中:
    • 文件模块:负责提供创建文件、打开文件、读取文件、写入文件、关闭文件、删除文件以及重命名文件共七个功能。
    • 文件目录模块:负责提供创建目录、切换目录、列出文件以及解析路径共四个功能。
    • 磁盘模块:负责提供存储记录、释放磁盘空间、读取记录、保存磁盘数据以及加载磁盘数据共五个功能。
    • 系统管理模块:系统管理模块有一个下属模块:打印信息模块,该模块负责提供显示文件列表、显示文件内容、显示帮助列表以及显示位示图共四个功能。

具体的系统模块图如图3.1所示。

图3.1 系统模块图

3.2.3抽象数据类型定义

系统用户信息实体类定义如下:

public class User implements Serializable {/*** 用户名*/private String username;/*** 密码*/private String password;
}

文件控制块实体类定义如下:

public class FileControlBlock implements Serializable {/*** 是否是目录文件*/private boolean isDirectory;/*** 文件名(包括了拓展名)*/private String fileName;/*** 拓展名*/private String suffix;/*** 起始盘块号*/private Integer startBlock;/*** 所占用的盘块数* 文件大小 = 一个盘块的大小 * 所占用的盘块数*/private Integer blockNum;/*** 文件属性:保护码列表*/private List<ProtectType> protectTypeList;/*** 创建时间*/private LocalDateTime createTime;/*** 最后一次修改时间*/private LocalDateTime updateTime;
}

树形目录结构实体类定义如下:

public class Directory implements Serializable {/*** 文件控制块*/private FileControlBlock fileControlBlock;/*** 在树形目录结构中的位置*/private Integer index;/*** 文件夹属性:子目录项集合*/private List<Directory> childDirectory;/*** 父目录项的位置*/private Integer parentIndex;

打开的文件信息实体类定义如下:

public class ActiveFile {/*** 文件控制块*/private FileControlBlock fileControlBlock;/*** 文件记录*/private List<Character> fileRecord;/*** 读指针*/private Integer readPtr;/*** 写指针*/private Integer writePtr;
}

虚拟磁盘空间实体类定义如下:

public class Disk implements Serializable {/*** List<Character>: 表示一个盘块* List<List<Character>>: 表示所有盘块的集合,即一个磁盘*/private List<List<Character>> disk;/*** 表示存储在该磁盘上的系统用户集*/private Map<String, User> userMap;/*** 表示存储在该磁盘上的所有文件控制块*/private List<FileControlBlock> fileControlBlockList;/*** 表示存储在该磁盘上的树形结构目录,第0个元素为根目录*/private List<Directory> directoryStruct;/*** 表示存储在该磁盘上的磁盘位示图*/private Integer[][] bitmap;
}
3.2.4主程序的流程图

主程序的流程图如图3.2所示。

图3.2 主程序流程图

3.3详细设计

3.3.1系统算法IPO表

表3.4~表3.26展示了本文件系统的各个功能的具体实现算法IPO表,介绍了各功能模块的编号、模块、日期、作者、被调用模块、输入输出、数据处理与相关数据。如下所示:

表3.4用户注册IPO表

表3.5用户登录IPO表

表3.6用户注销IPO表

表3.7创建文件IPO表

表3.8打开文件IPO表

表3.9读取文件IPO表

表3.10写入文件IPO表

表3.11关闭文件IPO表

表3.12删除文件IPO表

表3.13重命名文件IPO表

表3.14创建目录IPO表

表3.15切换目录IPO表

表3.16列出文件IPO表

表3.17解析路径IPO表

表3.18存储记录IPO表

表3.19释放磁盘空间IPO表

表3.20读取记录IPO表

表3.21保存磁盘数据IPO表

表3.22加载磁盘数据IPO表

表3.23显示文件列表IPO表

表3.24显示文件内容IPO表

表3.25显示帮助列表IPO表

表3.26显示位示图IPO表

3.4调试分析

一开始在实现树形结构目录的时候,我的文件目录项实体类是这样的:

public class Directory implements Serializable {/*** 文件控制块*/private FileControlBlock fileControlBlock;/*** 文件夹属性:子目录项集合*/private List<Directory> childDirectory;/*** 父目录项*/private Directory parentDirectory;
}

在一个目录项之中,持有其父目录项的引用,如果该目录项是目录文件的话,还持有归属于它的子目录项的集合,这样便可以实现一个树形结构的目录。而在磁盘中只要持有一个对根目录的引用就可以查找到所有的目录项,这样是很方便的一种实现方案。

但是,这样的实体类在程序实际运行起来的时候是有问题的。假设有这样的情形:directoryA是一个表示目录文件的目录项,directoryB是一个表示数据文件的目录项,并且directoryB的父目录项是directoryA。这样的关系,在程序中表现为,directoryA的childDirectory属性中持有对directoryB的引用,而directoryB的parentDirectory属性持有对directoryA的引用,这样就造成了循环引用。

这样的循环引用问题,在Java的序列化和反序列化的时候表现的尤为明显。因为本文件系统可以将系统运行过程中的磁盘数据保存到本地文件中,也可以将本地文件中的磁盘数据加载到程序中,前者是通过序列化实现的,后者是通过反序列化实现的。但是由于循环引用的问题,在进行序列化和反序列化的时候,会报栈溢出的错误,导致磁盘数据加载不了(表现为找不到本该存在的目录项)。

当时发现这个问题的时候,我通过IDEA的debug功能一步一步地调试,最终定位到问题的根源以及想出了解决方案。改进后的文件目录项实体类如下所示:

public class Directory implements Serializable {/*** 文件控制块*/private FileControlBlock fileControlBlock;/*** 在树形目录结构中的位置*/private Integer index;/*** 文件夹属性:子目录项集合*/private List<Directory> childDirectory;/*** 父目录项的位置*/private Integer parentIndex;
}

这样进行了修改之后,在磁盘中要保存的是整个树形目录结构的所有目录项的列表,如下所示:

public class Disk implements Serializable {.../*** 表示存储在该磁盘上的树形结构目录,第0个元素为根目录*/private List<Directory> directoryStruct;...
}

3.5系统测试

3.5.1 help命令测试

测试数据如下表:

前提条件命令输入执行结果结果分析
help显示本系统的帮助列表help命令功能正常

实际测试结果如下图所示:

3.5.2 exit命令测试

测试数据如下表:

前提条件命令输入执行结果结果分析
exit退出本系统exit命令功能正常

实际测试结果如下图所示:

3.5.3 register命令测试

测试数据如下表:

前提条件命令输入执行结果结果分析
register注册用户失败:用户名不能为空缺少[用户名]参数
register pw注册用户失败:密码不能为空缺少[密码]参数
[pw]这个用户没有被注册register pw 123注册用户成功register命令功能正常
[pw]这个用户已被注册register pw 123注册用户失败:该用户已存在[pw]是一个已存在的用户,不能重复注册

实际测试结果如下图所示:

3.5.4 login命令测试

测试数据如下表:

前提条件命令输入执行结果结果分析
login用户登录失败:该用户不存在缺少[用户名]参数,系统会判定[用户名]为空字符
login pw用户登录失败:密码错误缺少 [密码]参数,系统会判定[密码]为空字符
[pw]这个用户已被注册,且密码不是456login pw 456用户登录失败:密码错误[pw]这个用户的密码不正确
[unknown]这个用户没有被注册login unknown 123用户登录失败:该用户不存在[unknown]这个用户不存在(没有注册过)
[pw]这个用户已被注册,且密码是123login pw 123登录成功用户名和密码都正确,登录成功

实际测试结果如下图所示:

3.5.5 logout命令测试

测试数据如下表:

前提条件命令输入执行结果结果分析
已登录了某个用户logout注销成功logout命令功能正常
当前没有登录用户logout用户注销失败:当前没有登录用户logout命令功能正常

实际测试结果如下图所示:

3.5.6 show命令测试

测试数据如下表:

前提条件命令输入执行结果结果分析
show显示位示图信息show命令功能正常

实际测试结果如下图所示:

注意:以下命令能够正确执行前提都是要在已进行了登录的情况下,如果没有进行登录,系统会给出错误提示信息。所以下述命令的测试都是在已登录了的情况下进行的测试,此前提条件不再赘述,忘悉知。

3.5.7 mkdir命令测试

测试数据如下表:

前提条件命令输入执行结果结果分析
mkdir创建目录失败:文件名不能为空缺少[目录名]这个参数,系统会判定目录名为空字符
当前目录下不存在[os]这个子目录mkdir os创建成功,使用[dir]命令可以查看到[os]这个目录的信息mkdir命令功能正常
当前目录下存在[os]这个子目录mkdir os创建目录失败:文件名重复同一个目录中的文件不能重名

实际测试结果如下图所示:

3.5.8 dir命令测试

测试数据如下表:

前提条件命令输入执行结果结果分析
dir列出当前目录下面所有文件的信息dir命令功能正常

实际测试结果如下图所示:

3.5.9 cd命令测试

测试数据如下表:

前提条件命令输入执行结果结果分析
cd仍在当前目录如果缺少[目录路径]参数,则停留在当前目录下
当前目录下存在[os]这个子目录cd os进入到os目录cd命令功能正常
当前目录下不存在[os]这个子目录cd os切换目录失败:找不到对应目录cd命令功能正常
存在上一级目录cd …返回到上一级目录cd命令功能正常

实际测试结果如下图所示:

3.5.10 create命令测试

测试数据如下表:

前提条件命令输入执行结果结果分析
create创建文件失败:文件名不能为空缺少[文件名]这个参数,系统会判定文件名为空字符
当前目录下不存在[a.txt]这个文件create a.txt创建文件成功,使用[dir]命令可以查看到[a.txt]的信息create命令功能正常
当前目录下存在[a.txt]这个文件create a.txt创建文件失败:文件名重复同一个目录中的文件不能重名
当前目录下存在[a.txt]这个文件create A.txt创建文件失败:文件名重复本系统的文件名不区分大小写

实际测试结果如下图所示:

3.5.11 open命令测试

测试数据如下表:

前提条件命令输入执行结果结果分析
open打开文件失败:文件名不能为空缺少[文件名]这个参数,系统会判定文件名为空字符
当前目录下不存在[b.jpg]这个文件open b.jpg打开文件失败:文件不存在open命令功能正常
当前目录下存在[a.txt]这个文件open a.txt打开文件成功,显示出文件中的内容open命令功能正常

实际测试结果如下图所示:

3.5.12 close命令测试

测试数据如下表:

前提条件命令输入执行结果结果分析
当前存在已打开的文件close关闭成功close命令功能正常
当前不存在已打开的文件close关闭文件失败:当前没有文件被打开close命令功能正常

实际测试结果如下图所示:

3.5.13 write命令测试

测试数据如下表:

前提条件命令输入执行结果结果分析
当前不存在已打开的文件write,然后输入文件内容,以“###”结尾写入文件失败:请先打开文件再进行写入write命令功能正常
当前存在已打开的文件write,然后输入文件内容,以“###”结尾写入成功,控制台会回显文件的所有内容(包括刚刚写入的内容)write命令功能正常

实际测试结果如下图所示:

3.5.14 read命令测试

测试数据如下表:

前提条件命令输入执行结果结果分析
当前存在已打开的文件read显示空字符缺少[要读取的记录个数]参数,系统会判定要读取的记录个数为0
当前存在已打开的文件,且(当前读指针 + 5)< 文件长度read 5显示读取出来的5个字符read命令功能正常
当前存在已打开的文件,且(当前读指针 - 4)>= 0read -4显示读取出来的4个字符read命令支持向后读取

实际测试结果如下图所示:

3.5.15 delete命令测试

测试数据如下表:

前提条件命令输入执行结果结果分析
delete删除文件失败:文件名不能为空缺少[文件名]参数,系统会判定文件名为空字符
当前目录下不存在[b.jpg]这个文件delete b.jpg删除文件失败:找不到对应文件delete命令功能正常
当前目录下存在[a.txt]这个文件delete a.txt删除成功,使用[dir]命令查看a.txt文件不存在delete命令功能正常

实际测试结果如下图所示:

3.5.16 rename命令测试

测试数据如下表:

前提条件命令输入执行结果结果分析
rename重命名文件失败:文件名不能为空缺少[文件名]参数,系统会判定文件名为空字符
rename b.jpg重命名文件失败:文件名不能为空缺少[新文件名]参数,系统会判定新文件名为空字符
当前目录下不存在[b.jpg]这个文件rename b.jpg c.mp3重命名文件失败:文件不存在rename命令功能正常
当前目录下存在[a.txt]这个文件rename a.txt c.mp3重命名成功,使用[dir]命令可查看a.txt已变为c.mp3rename功能正常

实际测试结果如下图所示:

3.6使用说明

3.6.1操作命令说明

本文件系统支持的所有操作命令已在“帮助列表”中列出。想要查看“帮助列表”时只要键入 help 命令即可,如下所示:

现在对本文件系统中的几种操作命令格式做说明:

①无参数命令:例如help、show、exit、dir等都是无参数命令。在使用无参数命令时,只需要键入对应的命令即可,不需要输入额外的参数。如果输入的额外的参数,系统会默认把它丢弃掉,也并不影响使用。

②单参数命令:例如mkdir、create、open等都是单参数命令。使用单参数命令时,输入对应的命令之后,要输入一个(或者至少一个)空格,然后输入正确的参数,最后回车即可。在上述“帮助列表”中的“用法”中,方括号框中表示的是要输入的参数。例如mkdir [目录名],该命令正确的用法是“mkdir test”,表示创建一个名为“test”的新目录。

③多参数命令:例如register、login等都是要输入一个以上参数的命令。在使用多参数命令时,参数和参数之间要使用一个空格进行分隔开。另外,参数的个数要对应。例如在使用login [用户名] [密码],如果输入“login 123”,系统会把“123”当成用户名来识别,而该命令缺少了密码这个参数,系统给出错误提示。

另外,对本文件系统采用的文件路径格式做如下说明:

①目录名与目录名(或文件名)之前用路径分隔符“/”分隔开。例如“cd test/word”表示进入到当前目录下的test文件夹下的word文件夹中。

②全部采用相对路径

③“…”表示上一级目录。例如“cd …”表示回退到上一级目录。

3.6.2磁盘数据保存说明

本文件系统在启动的时候会加载“固定路径”下的“磁盘文件”中的磁盘数据,在正常退出的时候会保存磁盘数据到“固定路径”下的“磁盘文件”中。

“固定路径”是指程序运行文件所在目录中的save文件夹。“磁盘文件”是指save文件夹中的一个名为disk.ser的文件,本文件系统的所有磁盘数据都会保存进里面。如果本文件系统启动的时候找不到disk.ser文件(或save文件夹),系统会初始化磁盘,相当于一个新激活的系统。

本文件系统在正常退出(使用exit命令退出)的之前,会保存当前的磁盘数据到save文件夹中的disk.ser文件中。如果disk.ser文件不存在,会新建一个disk.ser文件;如果disk.ser文件存在,则会进行覆盖写入操作。

3 经验与体会

我的经验和体会是:

①在编程实现多级文件系统之前,要先确定好文件的逻辑结构、文件的物理结构、文件控制块信息、树形目录结构的表现形式、磁盘空间的表示显示、文件记录在磁盘中的表现形式、磁盘空间的分配方式、磁盘空间的管理形式等重要问题。只有思考了以上问题以及确定好具体的实现方案之后,才能着手与正式的编程实现,否则就在编程的同时遇到很多具有极强关联性的问题,导致了编程后期可能要对系统进行重构。

②在设计本文件系统的交互的时候,要考虑到用户的使用感受,应该使用户能以尽量简单的形式使用本系统,操作命令的输入不要过于冗余而繁杂。在这个方面可以参考很多优秀的操作系统的实现方式,比如Linux和Windows系统。

4 重要数据结构或疑难部分说明

4.1重要数据结构

大部分重要数据结构已经在之前的设计步骤中的需求分析的抽象数据类型定义小节中进行了说明,这里便不再赘述。关于树形结构目录的实现则在实体类Directory中。

4.2疑难部分说明

除了树形目录结构的具体实现比较难之外(该实现已在调试分析中进行说明),另一个疑难部分就是在存储文件记录时为文件记录分配磁盘空间和修改位示图的具体实现。存储文件记录的具体实现为:

public CommonResult<FileControlBlock> storeRecord(FileControlBlock fileControlBlock, List<Character> record) {if (CollectionUtil.isEmpty(record)) {return CommonResult.operateSuccess(null);}// 修改位示图,为重新分配盘块做准备changeBitmapStatus(fileControlBlock.getStartBlock(), fileControlBlock.getBlockNum(), true);// 计算存储该长度记录所需要的盘块数量Integer requiredNum = Math.ceilDivide(record.size(), DiskConstant.BLOCK_SIZE);int count = 0;int startBlockId = DiskConstant.RECORD_START_BLOCK;for (int i = 0; i < DiskConstant.BITMAP_ROW_LENGTH; i++) {for (int j = 0; j < DiskConstant.BITMAP_LINE_LENGTH; j++) {// 如果该盘块空闲if (DiskConstant.BITMAP_FREE.compareTo(Memory.getInstance().getBitmap()[i][j]) == 0) {if (count == 0) {// 记下起始盘块号: 当前行 * 总列数 + 当前列startBlockId = i * DiskConstant.BITMAP_LINE_LENGTH + j;}count++;if (count == requiredNum) {// 如果有足够的连续盘区供存储,则进行存储,并改变位示图的相应状态storeToDisk(startBlockId, record);changeBitmapStatus(startBlockId, requiredNum, false);return CommonResult.operateSuccess(fileControlBlock.setStartBlock(startBlockId).setBlockNum(requiredNum));}} else {// 因为是连续分配,如果该盘块不空闲则要重新计数count = 0;}}}return CommonResult.operateFailWithMessage("[分配盘块失败]: 磁盘空间不足");
}

在该方法中调用了两个关键的方法:storeToDisk(startBlockId, record)和changeBitmapStatus(startBlockId, requiredNum, false)。

其中的storeToDisk(startBlockId, record)方法的作用是将文件记录存储在磁盘中。传入参数startBlockId表示起始盘块号,传入参数record表示待存储的文件记录。其具体实现为:

private void storeToDisk(Integer startBlockId, List<Character> record) {int index = 0;int blockId = startBlockId;Disk disk = DataCache.getInstance().getDisk();// 可以直接覆盖掉原来的磁盘中的记录for (Character ch : record) {if (index >= DiskConstant.BLOCK_SIZE) {// 如果一个盘块的空间被用完了,则使用下一个盘块来进行存储blockId++;index = 0;}disk.getDisk().get(blockId).add(index, ch);index++;}while (index < DiskConstant.BLOCK_SIZE && disk.getDisk().get(blockId).size() > index) {// 擦除最后一个盘块中没有用到的空间disk.getDisk().get(blockId).set(index, null);index++;}
}

其中的changeBitmapStatus(startBlockId, requiredNum, false)方法的作用是更改相应的位示图的状态(仅适用于连续分配的方式)。传入参数startBlockId表示起始盘块号,传入参数blockNum表示要更改的盘块数量,传入参数changeToFree表示要更改的状态(true-表示空闲状态,false-表示已分配状态)。其具体实现为:

private void changeBitmapStatus(Integer startBlockId, Integer blockNum, boolean changeToFree) {if (Objects.isNull(startBlockId) || startBlockId < DiskConstant.RECORD_START_BLOCK ||startBlockId >= DiskConstant.BLOCK_NUM || blockNum <= 0) {return;}// 解析该盘块在位示图中的第几行int row = startBlockId / DiskConstant.BITMAP_LINE_LENGTH;// 解析该盘块在位示图中的第几列int line = startBlockId % DiskConstant.BITMAP_LINE_LENGTH;for (int i = 0; i < blockNum; i++) {Memory.getInstance().getBitmap()[row][line] = changeToFree ? DiskConstant.BITMAP_FREE : DiskConstant.BITMAP_BUSY;if (line >= DiskConstant.BITMAP_LINE_LENGTH - 1) {line = 0;row++;} else {line++;}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/434713.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

unreal engine5制作动作类游戏时,我们使用刀剑等武器攻击怪物或敌方单位时,发现攻击特效、伤害等没有触发

UE5系列文章目录 文章目录 UE5系列文章目录前言一、问题分析二、解决方法1. 添加项目设置碰撞检测通道2.玩家角色碰撞设置3.怪物角色碰撞预设 最终效果 前言 在使用unreal engine5制作动作类游戏时&#xff0c;我们使用刀剑等武器攻击怪物或敌方单位时&#xff0c;发现攻击特效…

Lesson08---string(4)类

Lesson08—string类&#xff08;4&#xff09; c第八章string类的实现 文章目录 Lesson08---string类&#xff08;4&#xff09;前言一、计算机是怎么储存文字的1. 在此之前先思考一个问题2.编码表2.1 ascll码2.2unicode码2.3UTF码2.4gbk码 二、实现一个简单的string1.构造函数…

解锁免费数据恢复工具的潜力,找回珍贵数据记忆

数据的分享与存储普遍倾向于电子化形式&#xff0c;这一转变无疑极大地提升了便捷性。然而&#xff0c;电子化存储也伴随着风险&#xff0c;诸如系统崩溃、误删除或外部因素干扰等意外情况&#xff0c;都可能导致宝贵数据的突然丢失。为了预防这一潜在问题&#xff0c;今天我们…

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-29

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-29 在这一期中&#xff0c;我们对大语言模型在软件开发中的跨学科应用的几个工作做简要的介绍。相关内容涵盖软件测试时的问题报告&#xff0c;问题分类&#xff0c;测试生成&#xff0c;和软件测试中的AI应用: …

97、配置 VXLAN 不同子网互访 (分布式网关)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、基础配置SW1SW2IGP IS-IS 二、VXLAN1.引入库 总结 前言 一、基础配置 SW1 vlan 10 vlan 20interface GigabitEthernet0/0/1port link-type accessport de…

【一篇文章理解Java中多级缓存的设计与实现】

文章目录 一.什么是多级缓存&#xff1f;1.本地缓存2.远程缓存3.缓存层级4.加载策略 二.适合/不适合的业务场景1.适合的业务场景2.不适合的业务场景 三.Redis与Caffine的对比1. 序列化2. 进程关系 四.各本地缓存性能测试对比报告(官方)五.本地缓存Caffine如何使用1. 引入maven依…

【Python】PyJWT:轻松实现 JSON Web Token (JWT) 网络令牌的生成与验证

PyJWT 是一个用 Python 实现的轻量级库&#xff0c;用于处理 JSON Web Token (JWT)。JWT 是一种安全的方式&#xff0c;用来表示双方之间经过签名的令牌&#xff0c;通常用于认证和授权场景。PyJWT 简化了 JWT 的生成和验证过程&#xff0c;使得开发者能够轻松地在 Python 项目…

Python | Leetcode Python题解之第443题压缩字符串

题目&#xff1a; 题解&#xff1a; class Solution:def compress(self, chars: List[str]) -> int:def reverse(left: int, right: int) -> None:while left < right:chars[left], chars[right] chars[right], chars[left]left 1right - 1n len(chars)write lef…

基于php摄影门户网站

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

Verilog:实例数组(重复实例化的快捷方法)

相关阅读 Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm1001.2014.3001.5482 前言 谈到重复实例化&#xff0c;一般都会想到for generate结构&#xff0c;但其实有一种更加简单的语法&#xff0c;只是使用的人不多&#xff0c;它就是实例数…

JavaScript 使用 Graham 扫描的凸包(Convex Hull using Graham Scan)

先决条件&#xff1a; 如何检查两个给定的线段是否相交&#xff1f; c https://blog.csdn.net/hefeng_aspnet/article/details/141713655 java https://blog.csdn.net/hefeng_aspnet/article/details/141713762 python https://blog.csdn.net/hefeng_aspnet/article/details/…

智能监控,守护绿色能源:EasyCVR在电站视频监控中心的一站式解决方案

随着科技的飞速发展&#xff0c;视频监控技术在社会安全、企业管理及智慧城市建设等领域中扮演着越来越重要的角色。特别是在电力行业中&#xff0c;电站作为能源供应的关键设施&#xff0c;其安全性和稳定性至关重要。传统的人工监控方式已难以满足现代电站复杂多变的运行需求…

基于SpringBoot+Vue+MySQL的甜品店管理系统

系统展示 用户前台界面 管理员后台界面 系统背景 在数字化浪潮的推动下&#xff0c;甜品店行业也面临着转型与升级的需求。传统的线下经营模式已难以满足现代消费者对于便捷、高效购物体验的追求。为了提升运营效率、优化顾客体验&#xff0c;我们设计了一款基于SpringBoot后端…

Ubuntu 16.04安装填坑记录

一. 问题描述&#xff1a; &#xff08;1&#xff09;Ubuntu 16.04使用USB启动盘安装时&#xff0c;出现"try ubuntu without installation"或“install ubuntu”选择&#xff0c;Enter选择安装后&#xff0c;显示器黑屏无任何显示。 原因分析&#xff1a; 显示黑…

遥感图像变换检测实践上手(TensorRT+UNet)

目录 简介 分析PyTorch示例 onnx模型转engine 编写TensorRT推理代码 main.cpp测试代码 小结 简介 这里通过TensorRTUNet&#xff0c;在Linux下实现对遥感图像的变化检测&#xff0c;示例如下&#xff1a; 可以先拉去代码&#xff1a;RemoteChangeDetection 分析PyTorch示…

网络攻击DDOoS的原理、攻击手段及防范措施详解

一、DDoS的原理 1. 原理 DDoS&#xff08;分布式拒绝服务攻击&#xff09;是利用大量的僵尸主机对受害者发起攻击&#xff0c;从而造成受害者的资源被耗尽无法为合法用户提供服务。DDoS一般采用三级结构&#xff0c;包括&#xff1a; 攻击者&#xff1a;攻击指令的发起方僵尸…

【鸿蒙HarmonyOS NEXT】数据存储之分布式键值数据库

【鸿蒙HarmonyOS NEXT】数据存储之分布式键值数据库 一、环境说明二、分布式键值数据库介绍三、示例代码加以说明四、小结 一、环境说明 DevEco Studio 版本&#xff1a; API版本&#xff1a;以12为主 二、分布式键值数据库介绍 KVStore简介&#xff1a; 分布式键值数据库…

OpenHarmony(鸿蒙南向)——平台驱动指南【DAC】

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 持续更新中…… 概述 功能简介 DAC&#xff08;Digital to Analog Converter&…

Python办公自动化之Word

在现代办公环境中&#xff0c;自动化无疑是提升工作效率的关键。特别是处理文档的工作&#xff0c;很多人可能花费大量时间在重复性任务上。那么&#xff0c;有没有一种方法可以让我们用 Python 来自动化 Word 文档的操作呢&#xff1f;今天&#xff0c;我们来聊聊如何用 Pytho…

AI Agent应用出路到底在哪?

1 Agent/Function Call 的定义 Overview of a LLM-powered autonomous agent system&#xff1a; Agent学会调用外部应用程序接口&#xff0c;以获取模型权重中缺失的额外信息&#xff08;预训练后通常难以更改&#xff09;&#xff0c;包括当前信息、代码执行能力、专有信息源…