java 实现模拟文件管理系统
前言
这个模拟文件管理系统是两年前的OS课设,因此代码和本博客叙述可能有所欠缺,若有问题欢迎指正。此博客仅供分享,如需要源代码做参考,请访问我的GitHub账号:https://github.com/Daisy-gj 。本系统我模仿了Windows的文件管理系统,有本机的文件增加、删除,饼状图显示本机各个盘的存储空间、保存所有操作到.TXT文件等等,见下面的表格
1. 系统功能表
2. 系统功能结构图
3. 模块功能简介
(1)本机文件的树型显示模块:
使用JTree来完成整个结构显示,树节点使用DefaultMutableTreeNode来定义,则可以使用其有关的系统方法。整个树的获取方式,以及点击树节点的监听的事件效果以及体现结果如下流程图所示:
(2)操作汇总模块:
将命令行操作的命令和操作执行时间单独放到一个TextArea中,点击“保存到本地”按钮,就可实现操作文件实时保存到本地。实现功能的流程图如下所示:
(3)命令行输入模块:
在Panel上设置一个JLable用于命令信息的输入,并将对命令的操作结果显示显示到操作结果面板—使用JTextArea显示。每个命令的执行主要使用java中file类的方法。实现功能的流程图如下所示:
对主要的操作命令的解释如下所示:
①改变目录:
当命令框中输入内容的格式如cd <目录名>时,为改变目录的命令,其后的目录名为想要打开的目录的绝对路径。对输入路径应该先判断是否存在,不存在则输出显示“文件不存在”,若是存在,则更改当前系统的路径,进行切换。该方法的主要代码如下:
public void cd(String path, String file) {
String temp = path + "\\" + file; //组合成相对路径
if (!isRightPath(temp)) {
mainFrame.display("没有找到这个文件夹"); //向操作结果面板上输出未找到的提示
} else {
if (!file.equals(""))
currentPath += "\\" + file; //为系统的当前路径
}
}
②查看存储空间模块:
声明Sigar对象,使用其方法获得本机的磁盘的使用情况,并用JFree类的对象绘制本机磁盘使用情况的饼状图。其模块功能流程图如下图所示:
③新建文件:
当命令框中输入内容的格式如edit<文件名>时,为新建文件的命令,其后的目录名为想要新建的文件的绝对路径。与系统当前的位置组合成相对路径,先判断该相对路径是否有文件存在,要是有,则输出“文件已经存在”,要是不存在,则按照该相对路径新建一个文件,该方法的主要代码如下:
public void edit(String file) {
if (!currentPath.equals("")) {
String temp = currentPath + "\\" + file;
File newFile = new File(temp);
if (newFile.exists()) {
mainFrame.display("文件已经存在!");
} else {
try {//使用file类的方法新建文件
newFile.createNewFile();
mainFrame.display("文件创建成功!");
} catch (Exception e) {
mainFrame.display("文件创建失败:" + e.getMessage());
}
}
}
}
④删除文件:
当命令框中输入内容的格式如del<文件名>时,为删除文件的命令,其后的目录名为想要删除的文件的绝对路径。与系统当前的位置组合成相对路径,先判断该相对路径是否有目录存在,要是没有,则输出“文件不存在”,要是存在,则删除该文件,该方法的主要代码如下:
public void del(String file) {
if (!file.equals("")) {
String temp = currentPath + "\\" + file;
File dfile = new File(temp);
if (dfile.exists()) {
if (dfile.delete()) {
mainFrame.display("文件删除成功!");
} else {
mainFrame.display("文件删除操作出错!");
}
} else {
mainFrame.display("文件不存在");
}
}
}
上述代码片段中设计的非库函数的方法都是自定义的,具体参见完整代码中查找出的方法定义
4. 关键代码及解释
①将结果返回输出到操作结果面板上的代码如下,在每个命令行操作后都调用该方法。
// 在回显框显示结果;
public void display(String str) {
echoArea.append(str + "\n");
echoArea.setCaretPosition(echoArea.getText().length());
cmdText.setText("");
}
②将命令行进行事件监听,一旦有内容输入且键盘上点击enter键后,就对命令进行执行,并且将命令执行的时间和命令写入操作汇总面板。代码如下:
private JTextField getCmdText() {
if (cmdText == null) {
cmdText = new JTextField();
cmdText.setColumns(25);
// 添加键盘监听事件;
cmdText.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyTyped(java.awt.event.KeyEvent e) {
}
public void keyPressed(java.awt.event.KeyEvent e) {
if (e.getKeyCode() == 10) {
//若键盘上点击enter键,则调用操作执行函数,并将命令和执行时间写入操作汇总面板
Date nowTime = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
String currTime = dateFormat.format( nowTime );
ftext=cmdText.getText();
insArea.setLineWrap(true); //激活自动换行功能
insArea.append("操作时间"+currTime+" 操作:"+ftext + "\n");
// 对文本进行处理;
try {
cmd.operate(cmdText.getText().trim());
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
});
}
return cmdText;
}
③根据输入的命令进行操作的函数,使用switch对命令的种类进行匹配,不同的命令分别调用不同的方法,并将要操作的路径进行传送和处理—将绝对路径与当前系统路径结合组成相对路径。代码如下:
public void operate(String operation) throws Exception {
String[] str = separate(operation);
// System.out.println(str.length);
String mycmd = "";
// mycmd对应的整数代号;
int mycmdInt = 0;
String path = "";
if (str.length == 1) {
mycmd = str[0];
if (mycmd.indexOf(":") != -1) {// 如果是直接盘符转换;执行些操作;
File newFile = new File(mycmd);
if (newFile.exists()) {
currentPath = mycmd;
// System.out.print(getPath());
mainFrame.display(getPath());
return;
}
}
}
if (str.length >= 2) {
mycmd = str[0];
path = str[1];
}
// 选择执行命令;
// ///System.out.println(mycmd+"\\"+path);
for (int i = 0; i < cmd.length; i++) {
if (mycmd.equalsIgnoreCase(cmd[i])) {
mycmdInt = cmdInt[i];
}
}
switch (mycmdInt) {
case 1:
cd(currentPath, path);
break;
case 2:
dir(currentPath);
break;
case 3:
md(path);
break;
case 4:
rd(path);
break;
case 5:
edit(path);
break;
case 6:
del(path);
break;
case 7:
exit();
break;
default:
mainFrame.display("无效的命令!");
}
mainFrame.display(getPath());
}
5. 运行结果
(1)首先运行程序之后的面板如下所示:
(2)点击菜单栏的“系统操作”的“查看存储空间”选项,可查看本机的各个盘片的存储空间的使用情况。
(3)点击菜单栏的“帮助”的“操作说明”选项,可查看改文件管理系统可进行的操作的详细信息。
(4)按照操作说明中的各个操作顺序操作,各个操作结果如下所示。





按顺序进行功能操作后,操作时间和操作内容都显示在右边的操作汇总栏目,点击“保存到本地”可以将这些记录保存到本机的指定TXT文件中。
心得体会
本系统难点在于JTree的结点与本机文件、目录的对应和对结点的点击的监听事件的编写。因为树型结构的限制,所以,不能将所有已经获取的结点都一次性显示在面板上,更加友好的应该是用户点击某个可以向下延伸(有子节点的结点)的结点后,可以实时显示出该节点的子节点的名称—需要点击的监听时间中有遍历的函数,并且能够迭代显示结点信息。为了实现功能,我决定在主面板生成时就生成结点,在点击后,直接查看并在此生成该子节点下的一级结点,并显示在面板上。并且在构造JTree时,需要注意各个结点的父子关系和兄弟关系的划分。
兄弟关系的划分。
其次,我使用了JFree去绘制饼状图,显示本机的存储空间的利用情况。对于统计图形的绘制使用JFree组件比Swing会方便很多,且绘制除的图形结果也更加美观。在绘制时,我参考了JFree的API的官方示例代码,所以问题比较少。
我在设计时使用的Swing的组件也有些使用的注意点,比如菜单栏使用的menubar和组成它的Jmenu、JmenuItem,在使用时要注意声明和定义的顺序,否则很容易出错。有多次编译时就出现了nullpointer错误。
我将之前一直想尝试的Sigar类对象获取计算机硬件信息、file类获取本机所有文档并用可视化的JTree显示、对文件进行操作、使用JFree绘制饼状图等都进行了实践。虽然在过程中有很多问题,但是经过查阅各个类的API和方法,以及更改程序的结构都得到了解决。
再次提醒,本程序的源代码在我的GitHub上可下载完整可运行的:https://github.com/Daisy-gj