【问题标题】:Java Command-Line App with own prompt [closed]带有自己提示符的 Java 命令行应用程序 [关闭]
【发布时间】:2016-06-27 09:29:21
【问题描述】:

我正在编写一个 JAVA 控制台应用程序。用户启动 jar 后,他应该得到一个类似于 Linux shell 的命令行,他可以在其中输入命令。这是我以前从未编程过的东西。通常我正在编写 GUI,或者我用一些已解析的参数启动 jar。

基本上我有两个问题:

  1. 是否有第三方库可以帮助从命令行读取用户输入并解析命令并生成提示?解析在我通常由 Apache Commons CLI 使用的主类中传递的参数。它在这里也使用完整还是有更好的方法?
  2. 是否有提供“无限输入”的最佳做法?我发现的所有解决方案都是 10 年或更长时间,例如:

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    while(true){
        System.out.print("Enter String");
        String s = br.readLine();
    }
    

    这仍然是最佳做法还是现在有更好的方法?

【问题讨论】:

  • “要求我们推荐或查找书籍、工具、软件库、教程或其他场外资源的问题对于 Stack Overflow 来说是无关紧要的,因为它们往往会吸引固执己见的答案和垃圾邮件。相反, describe the problem 以及迄今为止为解决它所做的工作。”
  • 您对 2 有什么顾虑?一大优势是它不依赖任何外部库...

标签: java command-line-tool apache-commons-cli jline jline2


【解决方案1】:

我也在构建一个带有命令行界面的应用程序。我设计的方式是创建一个名为“command”的类,它是所有命令的超类。制作 2 个抽象方法,“execute”和“getName()”。

然后,覆盖每个命令子类中的 getName() 方法,以便它将用户输入的命令作为字符串返回。 (您不必使用 getName(),任何其他方法名称都可以使用,或者您可以覆盖 toString(),但这并不理想,因为它不会强制子类拥有自己的实现)

让另一个名为“execute”的方法获取命令条目的其余部分(参数)和每个命令的逻辑。

获取用户输入,然后您可以通过遍历所有命令的列表来尝试将其与 command.getName() 方法匹配,而不是使用大量的大小写切换代码部分。不然会变丑的。

FWIW,我将控制台类设置为 Singleton,以便可以从应用程序的任何其他部分轻松访问它。

【讨论】:

  • 处理命令的有趣方法。我会试试的。
【解决方案2】:

我正在使用库 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();

【讨论】:

  • 我与 jline2 取得了联系,这正是我所需要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-08
  • 1970-01-01
  • 1970-01-01
  • 2013-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多