Java-приложение командной строки с собственной подсказкой

Я пишу JAVA-консольное приложение. После того, как пользователь запустил jar, он должен получить командную строку, подобную оболочке Linux, где он может вводить команды. Это то, что я никогда не программировал раньше. Обычно я пишу графические интерфейсы или начинаю банку с разбираемых аргументов.

В основном у меня есть 2 вопроса:

  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();
    }
    

    Это все еще лучшая практика или есть лучший способ сегодня?

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();

Я также нахожусь в процессе создания приложения с интерфейсом, похожим на командную строку. Я разработал свой способ создания одного класса под названием "команда", который является суперклассом для всех команд. Сделайте 2 абстрактных метода: "execute" и "getName()".

Затем переопределите метод getName () в каждом дочернем классе команды, чтобы он возвращал команду, которую пользователь введет в виде строки. (вам не нужно использовать getName(), любое другое имя метода будет работать, или вы можете переопределить toString(), но это не идеально, так как это не заставляет дочерний класс иметь собственную реализацию)

Пусть другой метод с именем execute выполнит оставшуюся часть ввода команды (параметры) и логику для каждой команды.

Возьмите пользовательский ввод, затем вы можете просто попытаться сопоставить его с методом command.getName(), выполнив итерацию по списку всех команд вместо использования огромного раздела кода с переключателем регистра. В противном случае это будет ужасно.

FWIW, у меня есть класс консоли как Singleton, так что он может быть легко доступен из любой другой части приложения.

Другие вопросы по тегам