Java 带有自己提示的命令行应用程序
Java Command-Line App with own prompt
我正在编写一个 JAVA-控制台应用程序。用户启动 jar 后,他应该得到一个类似 Linux shell 的命令行,他可以在其中输入命令。这是我以前从未编程过的东西。通常我正在编写 GUI,或者我用一些已解析的参数启动 jar。
基本上我有 2 个问题:
- 是否有第三方库可以帮助从命令行读取用户输入来解析命令并生成提示?为了解析在主要 class 中传递的参数,我通常使用 Apache Commons CLI。在这里也使用 full 还是有更好的方法?
是否有提供 "infinite input" 的最佳实践?我找到的所有解决方案都已有 10 年或更长时间,例如:
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while(true){
System.out.print("Enter String");
String s = br.readLine();
}
这仍然是最佳做法还是现在有更好的方法?
我也正在使用类似命令行的界面构建应用程序。我设计我的方法是创建一个名为 "command" 的 class,它是所有命令的超级 class。创建 2 个抽象方法,"execute," 和 "getName()".
然后,重写每个子命令 class 中的 getName() 方法,以便它将 return 用户将作为字符串输入的命令。 (您不必使用 getName(),任何其他方法名称都可以,或者您可以覆盖 toString(),但这并不理想,因为它不会强制子 class 拥有它的自己的实现)
使用另一个名为 "execute" 的方法获取命令条目的其余部分(参数)和每个命令的逻辑。
获取用户输入,然后您可以通过遍历所有命令的列表来尝试将其与 command.getName() 方法匹配,而不是使用巨大的大小写切换代码部分。否则会变丑。
FWIW,我将控制台 class 作为单例,以便可以从应用程序的任何其他部分轻松访问它。
我正在使用库 jline2,也就是说,使用它很简单:
InputStream inStream = new FileInputStream(FileDescriptor.in);
ConsoleReader reader = new ConsoleReader("App", inStream, System.out, null);
reader.setPrompt("> ");
reader.addCompleter(new FileNameCompleter());
reader.addCompleter(new StringsCompleter(Arrays.asList(new String[] {
"cmd1",
"exit",
"quit",
})));
String line;
PrintWriter out = new PrintWriter(reader.getOutput());
while ((line = reader.readLine()) != null) {
if (line.startsWith("cmd1")) {
String[] cmd = line.split("\s+");
if(cmd.length < 2) {
out.println("Invalid command");
help(out);
} else {
... do work
}
} else if (line.equalsIgnoreCase("quit") || line.equalsIgnoreCase("exit")) {
break;
} else {
help(out);
}
}
// ensure that all content is written to the screen at the end to make unit tests stable
reader.flush();
我正在编写一个 JAVA-控制台应用程序。用户启动 jar 后,他应该得到一个类似 Linux shell 的命令行,他可以在其中输入命令。这是我以前从未编程过的东西。通常我正在编写 GUI,或者我用一些已解析的参数启动 jar。
基本上我有 2 个问题:
- 是否有第三方库可以帮助从命令行读取用户输入来解析命令并生成提示?为了解析在主要 class 中传递的参数,我通常使用 Apache Commons CLI。在这里也使用 full 还是有更好的方法?
是否有提供 "infinite input" 的最佳实践?我找到的所有解决方案都已有 10 年或更长时间,例如:
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); while(true){ System.out.print("Enter String"); String s = br.readLine(); }
这仍然是最佳做法还是现在有更好的方法?
我也正在使用类似命令行的界面构建应用程序。我设计我的方法是创建一个名为 "command" 的 class,它是所有命令的超级 class。创建 2 个抽象方法,"execute," 和 "getName()".
然后,重写每个子命令 class 中的 getName() 方法,以便它将 return 用户将作为字符串输入的命令。 (您不必使用 getName(),任何其他方法名称都可以,或者您可以覆盖 toString(),但这并不理想,因为它不会强制子 class 拥有它的自己的实现)
使用另一个名为 "execute" 的方法获取命令条目的其余部分(参数)和每个命令的逻辑。
获取用户输入,然后您可以通过遍历所有命令的列表来尝试将其与 command.getName() 方法匹配,而不是使用巨大的大小写切换代码部分。否则会变丑。
FWIW,我将控制台 class 作为单例,以便可以从应用程序的任何其他部分轻松访问它。
我正在使用库 jline2,也就是说,使用它很简单:
InputStream inStream = new FileInputStream(FileDescriptor.in);
ConsoleReader reader = new ConsoleReader("App", inStream, System.out, null);
reader.setPrompt("> ");
reader.addCompleter(new FileNameCompleter());
reader.addCompleter(new StringsCompleter(Arrays.asList(new String[] {
"cmd1",
"exit",
"quit",
})));
String line;
PrintWriter out = new PrintWriter(reader.getOutput());
while ((line = reader.readLine()) != null) {
if (line.startsWith("cmd1")) {
String[] cmd = line.split("\s+");
if(cmd.length < 2) {
out.println("Invalid command");
help(out);
} else {
... do work
}
} else if (line.equalsIgnoreCase("quit") || line.equalsIgnoreCase("exit")) {
break;
} else {
help(out);
}
}
// ensure that all content is written to the screen at the end to make unit tests stable
reader.flush();