网站电脑基础培训班,深圳建筑设计网站,网页制作框架教程,无锡有哪些做网站的公司Java小型操作系统模拟 项目说明第一阶段#xff1a;反射结合策略模式搭建基本的命令结构第二阶段#xff1a;注解结合反射与策略模式#xff0c;将结构进一步规范第三阶段#xff1a;开启新的窗口#xff0c;将控制台输入切换到新窗口中#xff0c;同时创建右键菜单… Java小型操作系统模拟 项目说明第一阶段反射结合策略模式搭建基本的命令结构第二阶段注解结合反射与策略模式将结构进一步规范第三阶段开启新的窗口将控制台输入切换到新窗口中同时创建右键菜单使效果贴近命令行第四阶段发现IDEA的编译与命令行编译不一致且导致类装载出错的情况进行处理--重新编写初始化的装载方法第五阶段解决打包为jar后的装载问题及采用脚本自动编译项目下载 项目说明 主要是为了学习Java反射的知识以及对操作系统的一些概念进行回顾搭建了一个小型的操作系统包括基本的一些命令如clear、help、cd、mkdir、ls等同时支持用户及角色创建密码登录等相关文件采用加密存储在本地同时采用资源分配的形式设计了磁盘资源和内存资源采用首次适应、循环首次适应、最佳适应、最坏适应等策略采用Java的Socket通信设计了简单的socket通信模式 第一阶段反射结合策略模式搭建基本的命令结构 采用配置文件的形式指定命令的名称、描述与对应类的全路径采用反射的形式创建对象并装载到容器中策略模式结合HashMap的形式可以较为方便的获取到命令对象并执行对应的策略方法。 策略模式的体现采用Map进行命令策略的管理 package os.strategy;import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;/*** author bbyh* date 2023-07-27 21:19* description*/
public abstract class BaseStrategy {private static final MapString, BaseStrategy STRATEGY_FACTORY new HashMap(4);private static final MapString, String STRATEGY_DOC new HashMap(4);private final String name;private final String doc;public BaseStrategy(String name, String doc) {this.name name;this.doc doc;}protected final void register() {STRATEGY_FACTORY.put(name, this);STRATEGY_DOC.put(name, doc);}public abstract void execute();public static BaseStrategy getStrategy(String name) {if (!STRATEGY_FACTORY.containsKey(name)) {throw new UnsupportedOperationException(该策略还不支持);}return STRATEGY_FACTORY.get(name);}public static SetString getCommandNameSet() {return new HashSet(STRATEGY_FACTORY.keySet());}public static MapString, String getCommandDoc() {return new HashMap(STRATEGY_DOC);}
}采用配置文件结合反射装载对象分为只装载指定目录或装载指定目录及其子目录要求都是基础策略类的子类 package os.util;import os.strategy.BaseStrategy;import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.Properties;/*** author bbyh* date 2023/7/28 12:19*/
public class OsApplication {private static final String PACKAGE_PREFIX src/;private static final String DEFAULT_STRATEGY_PACKAGE strategy.impl;private static final String OS_COMMAND_PROPERTIES os-command-config.properties;private static final HashSetClass? CLASS_SET new HashSet(4);private static void load() {for (Class? instance : CLASS_SET) {if (instance.getSuperclass() BaseStrategy.class) {try (InputStream inputStream Files.newInputStream(Paths.get(OS_COMMAND_PROPERTIES))) {Properties properties new Properties();properties.load(inputStream);if (properties.containsKey(instance.getName())) {String[] split properties.getProperty(instance.getName()).split(,);try {Constructor? constructor instance.getConstructor(String.class, String.class);Object newInstance constructor.newInstance(split[0], split[1]);Method register newInstance.getClass().getSuperclass().getDeclaredMethod(register);register.setAccessible(true);register.invoke(newInstance);} catch (NoSuchMethodException | InvocationTargetException |IllegalAccessException | InstantiationException e) {throw new RuntimeException(e);}}} catch (IOException e) {throw new RuntimeException(e);}}}}public static void runWithSpecifiedDirectory(Class? application) {initSpecifiedDirectory(application.getPackage().getName() . DEFAULT_STRATEGY_PACKAGE);load();}private static void initSpecifiedDirectory(String scanPackage) {File basePackage new File(PACKAGE_PREFIX scanPackage.replace(., /));File[] files basePackage.listFiles(file - file.getName().endsWith(.java));loadClasses(scanPackage, files);}private static void loadClasses(String scanPackage, File[] files) {if (files ! null) {for (File file : files) {try {Class? instance Class.forName(scanPackage . file.getName().replace(.java, ));CLASS_SET.add(instance);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}}}}public static void runWithRecursiveDirectory(Class? application) {initRecursiveDirectory(application.getPackage().getName());load();}private static void initRecursiveDirectory(String scanPackage) {File basePackage new File(PACKAGE_PREFIX scanPackage.replace(., /));File[] files basePackage.listFiles(file - {if (file.isDirectory()) {initRecursiveDirectory(scanPackage . file.getName());}return file.getName().endsWith(.java);});loadClasses(scanPackage, files);}
}配置文件 os.strategy.impl.ClearStrategyclear,清屏命令清空屏幕
os.strategy.impl.HelpStrategyhelp,帮助命令查看当前系统支持的命令项目结构 第二阶段注解结合反射与策略模式将结构进一步规范 采用类似SpringBoot的启动方式自动装载指定目录下的命令类采用注解的形式设置命令的名称与描述 采用注解设置启动装载包目录名以及各个策略类的目录名称与相关说明 package os.annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** author bbyh* date 2023/7/2 15:29*/
Target(ElementType.TYPE)
Retention(RetentionPolicy.RUNTIME)
public interface StrategyScan {String value() default strategy.impl;
}help命令简单输出系统支持的命令和说明 package os.strategy.impl;import os.annotation.StrategyAnnotation;
import os.annotation.StrategyDocAnnotation;
import os.strategy.BaseStrategy;import java.util.Map;
import java.util.Set;/*** author bbyh* date 2023-07-27 21:26* description*/
StrategyAnnotation(commandName help)
StrategyDocAnnotation(commandDoc 帮助命令查看当前系统支持的命令)
public class HelpStrategy extends BaseStrategy {public HelpStrategy(String name, String doc) {super(name, doc);}Overridepublic void execute() {System.out.println(系统支持的命令);SetString commandNameSet BaseStrategy.getCommandNameSet();MapString, String commandDoc BaseStrategy.getCommandDoc();for (String commandName : commandNameSet) {System.out.println(commandName commandDoc.get(commandName));}}
}同样加载指定目录下携带注解的策略子类或者加载目录及其子目录的所有符合条件的类 package os.util;import os.annotation.StrategyAnnotation;
import os.annotation.StrategyDocAnnotation;
import os.annotation.StrategyScan;
import os.strategy.BaseStrategy;import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;/*** author bbyh* date 2023/7/28 12:19*/
public class OsApplication {private static final String PACKAGE_PREFIX src/;private static final HashSetClass? CLASS_SET new HashSet(4);private static void load() {for (Class? instance : CLASS_SET) {if (instance.getSuperclass() BaseStrategy.class) {try {StrategyAnnotation nameAnnotation instance.getAnnotation(StrategyAnnotation.class);StrategyDocAnnotation docAnnotation instance.getAnnotation(StrategyDocAnnotation.class);if (nameAnnotation ! null docAnnotation ! null) {Constructor? constructor instance.getConstructor(String.class, String.class);Object newInstance constructor.newInstance(nameAnnotation.commandName(), docAnnotation.commandDoc());Method register newInstance.getClass().getSuperclass().getDeclaredMethod(register);register.setAccessible(true);register.invoke(newInstance);}} catch (NoSuchMethodException | InvocationTargetException |IllegalAccessException | InstantiationException e) {throw new RuntimeException(e);}}}}/*** 加载配置目录下的添加了StrategyAnnotation注解的类** param application 启动类*/public static void runWithSpecifiedDirectory(Class? application) {StrategyScan strategyScan application.getAnnotation(StrategyScan.class);initSpecifiedDirectory(application.getPackage().getName() . strategyScan.value());load();}private static void initSpecifiedDirectory(String scanPackage) {File basePackage new File(PACKAGE_PREFIX scanPackage.replace(., /));File[] files basePackage.listFiles(file - file.getName().endsWith(.java));loadClasses(scanPackage, files);}private static void loadClasses(String scanPackage, File[] files) {if (files ! null) {for (File file : files) {try {Class? instance Class.forName(scanPackage . file.getName().replace(.java, ));CLASS_SET.add(instance);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}}}}/*** 加载配置目录及其子目录下的添加了StrategyAnnotation注解的类** param application 启动类*/public static void runWithRecursiveDirectory(Class? application) {initRecursiveDirectory(application.getPackage().getName());load();}private static void initRecursiveDirectory(String scanPackage) {File basePackage new File(PACKAGE_PREFIX scanPackage.replace(., /));File[] files basePackage.listFiles(file - {if (file.isDirectory()) {initRecursiveDirectory(scanPackage . file.getName());}return file.getName().endsWith(.java);});loadClasses(scanPackage, files);}
}项目结构 第三阶段开启新的窗口将控制台输入切换到新窗口中同时创建右键菜单使效果贴近命令行 经过测试发现上面两个系统在初始化加载类时有一些小问题因为在实际使用时都是执行class文件而在IDEA里面的执行是以Java文件为路径的需要进行一些简单的小修改当前这个阶段主要以IDEA里面的运行为主后面再对路径和初始化逻辑进行一些调整来保证兼容性 主窗体 package os.util;import os.strategy.BaseStrategy;import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.*;
import java.io.IOException;/*** author bbyh* date 2023-07-29 15:51* description*/
public class MainFrame extends JFrame {public static final JLabel DISPLAY new JLabel();private static final String DEFAULT_WORD_DIR C:\\root;public MainFrame() {setTitle(BBYH OS System);setSize(1000, 600);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setLocationRelativeTo(null);JScrollPane scrollPane new JScrollPane(DISPLAY);DISPLAY.setOpaque(true);DISPLAY.setBackground(Color.WHITE);setLayout(new GridLayout(1, 1));add(scrollPane);setVisible(true);Font font new Font(Consolos, Font.PLAIN, 24);DISPLAY.setFont(font);DISPLAY.setVerticalAlignment(SwingConstants.TOP);DISPLAY.setFocusable(true);init();// 右键菜单JPopupMenu rightMenu new JPopupMenu();JMenuItem backgroundItem new JMenuItem();JMenuItem fontItem new JMenuItem();JMenuItem copyItem new JMenuItem();backgroundItem.setFont(font);fontItem.setFont(font);copyItem.setFont(font);backgroundItem.setText(设置背景颜色);fontItem.setText(设置字体颜色);copyItem.setText(复制剪切版内容);rightMenu.add(backgroundItem);rightMenu.add(fontItem);rightMenu.add(copyItem);backgroundItem.addActionListener(evt - {Color color JColorChooser.showDialog(null, 设置背景颜色, Color.WHITE);if (color ! null) {DISPLAY.setBackground(color);}});fontItem.addActionListener(evt - {Color color JColorChooser.showDialog(null, 设置字体颜色, Color.BLACK);if (color ! null) {DISPLAY.setForeground(color);}});copyItem.addActionListener(evt - {Clipboard clipboard Toolkit.getDefaultToolkit().getSystemClipboard();Transferable transferable clipboard.getContents(null);if (transferable ! null) {if (transferable.isDataFlavorSupported(DataFlavor.stringFlavor)) {try {String data (String) clipboard.getData(DataFlavor.stringFlavor);appendDisplay(data);} catch (UnsupportedFlavorException | IOException e) {throw new RuntimeException(e);}}}});DISPLAY.addKeyListener(new KeyAdapter() {Overridepublic void keyPressed(KeyEvent e) {char keyChar e.getKeyChar();if (keyChar KeyEvent.VK_BACK_SPACE !.equals(getContent())) {DISPLAY.setText(getContent().substring(0, getContent().length() - 1));appendDisplay();} else if (keyChar KeyEvent.VK_ENTER) {appendDisplay(br /);try {BaseStrategy.getStrategy(Context.getNextCommand()).execute();} catch (Exception ex) {appendDisplay(ex.getMessage() br /);}appendDisplay(Context.getWorkDir());} else if (Character.isLetterOrDigit(keyChar)) {appendDisplay(String.valueOf(keyChar));}}});DISPLAY.addMouseListener(new MouseAdapter() {Overridepublic void mouseClicked(MouseEvent e) {if (e.getButton() MouseEvent.BUTTON3) {rightMenu.show(DISPLAY, e.getX(), e.getY() - 10);}}});}private static void init() {Context.setWorkDir(DEFAULT_WORD_DIR);appendDisplay(DEFAULT_WORD_DIR);}public static void appendDisplay(String content) {DISPLAY.setText(htmlbody stylepadding: 20px 10px getContent() content /body/html);}private static String getContent() {return DISPLAY.getText().replace(htmlbody stylepadding: 20px 10px, ).replace(/body/html, );}
}Context上下文操作类 package os.util;/*** author bbyh* date 2023-07-27 22:23* description*/
public class Context {private static String workDir;public static String getWorkDir() {return workDir;}public static void setWorkDir(String workDir) {Context.workDir workDir;}public static String getNextCommand() {String text MainFrame.DISPLAY.getText();return text.substring(text.lastIndexOf(getWorkDir()) getWorkDir().length(), text.lastIndexOf(br //body/html));}
}主程序 package os;import os.annotation.StrategyScan;
import os.util.MainFrame;
import os.util.OsApplication;/*** author bbyh* date 2023-07-27 21:18* description*/
StrategyScan
public class Main {public static void main(String[] args) {OsApplication.runWithRecursiveDirectory(Main.class);new MainFrame();}
}测试运行效果展示 第四阶段发现IDEA的编译与命令行编译不一致且导致类装载出错的情况进行处理–重新编写初始化的装载方法 采用getResource方法获取类路径来装在class文件同时采用脚本来解决javac命令行执行时无法编译不被别的文件依赖的策略实现类 重新编写的装载方法采用递归装载装载启动类目录下及其子目录中带有注解的策略实现类 package os.util;import os.annotation.StrategyAnnotation;
import os.annotation.StrategyDocAnnotation;
import os.strategy.BaseStrategy;import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Objects;/*** author bbyh* date 2023/7/28 12:19*/
public class OsApplication {private static final HashSetClass? CLASS_SET new HashSet(4);private static String BASE_PATH;/*** 加载配置目录及其子目录下的添加了StrategyAnnotation注解的类** param application 启动类*/public static void runWithRecursiveDirectory(Class? application) {BASE_PATH Objects.requireNonNull(application.getResource(/)).getPath();initRecursiveDirectory(application.getPackage().getName());load();}private static void initRecursiveDirectory(String packageName) {File[] files new File(BASE_PATH packageName.replace(., System.getProperty(file.separator))).listFiles(file - {if (file.isDirectory()) {initRecursiveDirectory(packageName . file.getName());}return file.getName().endsWith(.class);});loadClasses(packageName, files);}private static void load() {for (Class? instance : CLASS_SET) {if (instance.getSuperclass() BaseStrategy.class) {try {StrategyAnnotation nameAnnotation instance.getAnnotation(StrategyAnnotation.class);StrategyDocAnnotation docAnnotation instance.getAnnotation(StrategyDocAnnotation.class);if (nameAnnotation ! null docAnnotation ! null) {Constructor? constructor instance.getConstructor(String.class, String.class);Object newInstance constructor.newInstance(nameAnnotation.commandName(), docAnnotation.commandDoc());Method register newInstance.getClass().getSuperclass().getDeclaredMethod(register);register.setAccessible(true);register.invoke(newInstance);}} catch (NoSuchMethodException | InvocationTargetException |IllegalAccessException | InstantiationException e) {throw new RuntimeException(e);}}}}private static void loadClasses(String packageName, File[] files) {if (files ! null) {for (File file : files) {try {Class? instance Class.forName(packageName . file.getName().replace(.class, ));CLASS_SET.add(instance);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}}}}
}需要注意的一点是目前采用getResource方法对于打包为jar包时则会报空指针错误后续将考虑采用新方法装载来解决该问题 第五阶段解决打包为jar后的装载问题及采用脚本自动编译 自动编译的脚本Windows mkdir out
cd src
javac -d ../out os/Main.java os/strategy/impl/*.java -encoding UTF-8cd ../outjava os.Main自动编译的脚本Linux #!/bin/bash
mkdir out
cd src
javac -d ../out os/Main.java os/strategy/impl/*.java -encoding UTF-8
cd ../out
java os.Main需要注意几点小问题脚本.sh需要在Linux下创建使用同时需要给它赋予x执行权限chmod x javac_os_java.sh然后在执行时还需要对XShell安装一下图形服务x11参考文章xshell-linux 启动 jmeter 报 No X11 DISPLAY variable was set, but this program performed …不过这个Xming对中文的显示有问题有点难办 主函数根据启动不一样采用不一样的装载策略 package os;import os.annotation.StrategyScan;
import os.util.MainFrame;
import os.util.OsApplication;import java.util.Objects;/*** author bbyh* date 2023-07-27 21:18* description*/
StrategyScan
public class Main {public static boolean applicationRunning true;private static final String FILE_PROTOCOL file;private static final String JAR_PROTOCOL jar;public static void main(String[] args) {String protocol Objects.requireNonNull(OsApplication.class.getResource()).getProtocol();if (Objects.equals(protocol, FILE_PROTOCOL)) {OsApplication.runWithRecursiveDirectory(Main.class);} else if (Objects.equals(protocol, JAR_PROTOCOL)) {OsApplication.runWithRecursiveJar(Main.class);}new MainFrame();}
}装载工具类 package os.util;import os.annotation.StrategyAnnotation;
import os.annotation.StrategyDocAnnotation;
import os.strategy.BaseStrategy;import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Objects;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;/*** author bbyh* date 2023/7/28 12:19*/
public class OsApplication {private static final HashSetClass? CLASS_SET new HashSet(4);private static String BASE_PATH;public static final String FILE_SEPARATOR /;private static final String PREFIX_FILE file:;private static final String PREFIX_JAR jar:file:;private static final String SUFFIX_CLASS .class;/*** 加载配置目录及其子目录下的添加了StrategyAnnotation注解的类** param application 启动类*/public static void runWithRecursiveDirectory(Class? application) {BASE_PATH Objects.requireNonNull(application.getResource()).toString().replace(PREFIX_FILE, );String packageName application.getPackage().getName();BASE_PATH BASE_PATH.substring(0, BASE_PATH.lastIndexOf(/ packageName /)) FILE_SEPARATOR;initRecursiveDirectory(packageName);load();}private static void initRecursiveDirectory(String packageName) {File[] files new File(BASE_PATH packageName.replace(., FILE_SEPARATOR)).listFiles(file - {if (file.isDirectory()) {initRecursiveDirectory(packageName . file.getName());}return file.getName().endsWith(SUFFIX_CLASS);});loadFileClasses(packageName, files);}private static void loadFileClasses(String packageName, File[] files) {if (files ! null) {for (File file : files) {try {Class? instance Class.forName(packageName . file.getName().replace(SUFFIX_CLASS, ));CLASS_SET.add(instance);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}}}}private static void load() {for (Class? instance : CLASS_SET) {if (instance.getSuperclass() BaseStrategy.class) {try {StrategyAnnotation nameAnnotation instance.getAnnotation(StrategyAnnotation.class);StrategyDocAnnotation docAnnotation instance.getAnnotation(StrategyDocAnnotation.class);if (nameAnnotation ! null docAnnotation ! null) {Constructor? constructor instance.getConstructor(String.class, String.class);Object newInstance constructor.newInstance(nameAnnotation.commandName().split( )[0], docAnnotation.commandDoc());Method register newInstance.getClass().getSuperclass().getDeclaredMethod(register);register.setAccessible(true);register.invoke(newInstance);}} catch (NoSuchMethodException | InvocationTargetException |IllegalAccessException | InstantiationException e) {throw new RuntimeException(e);}}}}public static void runWithRecursiveJar(Class? application) {BASE_PATH Objects.requireNonNull(application.getResource()).toString().replace(PREFIX_JAR, );BASE_PATH BASE_PATH.substring(0, BASE_PATH.lastIndexOf(!/ application.getPackage().getName() /)) FILE_SEPARATOR;initRecursiveJar();load();}private static void initRecursiveJar() {try (JarFile jarFile new JarFile(BASE_PATH)) {EnumerationJarEntry jarEntryEnumeration jarFile.entries();while (jarEntryEnumeration.hasMoreElements()) {JarEntry jarEntry jarEntryEnumeration.nextElement();if (jarEntry.getName().endsWith(SUFFIX_CLASS)) {Class? instance Class.forName(jarEntry.getName().replace(SUFFIX_CLASS, ).replace(/, .));CLASS_SET.add(instance);}}} catch (IOException | ClassNotFoundException e) {throw new RuntimeException(e);}}}运行效果 项目下载 Gitee链接–Java模拟操作系统