Как написать «нажата клавиша ввода» в поток? - PullRequest
6 голосов
/ 08 февраля 2011

Извините за этот странный заголовок ...

У меня следующая ситуация: я хочу, чтобы моя Java-программа взаимодействовала с внешней консолью.Чтобы «отправить» отдельные команды на эту консоль, мне нужно смоделировать то, что будет «нажатием клавиши ввода» на обычной консоли.Чтобы прояснить, что я хочу, представьте, что у mysql нет другого API, и мне нужно будет взаимодействовать через консоль.Хотя это не моя настоящая проблема, она достаточно близка.

У меня есть следующий код:

        String command = "/usr/local/mysql/bin/mysql";
        Process child = Runtime.getRuntime().exec(command);

        StreamGobbler gobbler = new StreamGobbler(child.getInputStream());
        gobbler.start();

        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(child.getOutputStream()));
        out.write("help");
        // here enter key needs to be pressed
        out.flush();
        // out.close();

Если выполняется вызов out.close(), все в порядке.Но, конечно, таким образом я могу отправить только одну команду, а это не то, что я хочу.Но если out.close() опущено, другая программа никогда не выполнит команду.Я предполагаю, что он по-прежнему ожидает команды «финишировать», что на обычной консоли будет сделано нажатием клавиши ввода.out.write(System.getProperty("line.separator")); и out.newLine(); (которые одинаковы) не решают проблему, равно как и out.write("\r\n"); и out.write((char) 26); (EOF).

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

Любая помощь по этому вопросу высоко ценится.

Ответы [ 3 ]

7 голосов
/ 08 февраля 2011

Следующий код отлично работает как в Windows 7, использующей Java 1.6.0_23, так и в Ubuntu 8.04, использующей Java 1.6.0_22:

public class Laj {

  private static class ReadingThread extends Thread {
    private final InputStream inputStream;
    private final String name;

    public ReadingThread(InputStream inputStream, String name) {
      this.inputStream = inputStream;
      this.name = name;
    }

    public void run() {
      try {
        BufferedReader in = new BufferedReader(
            new InputStreamReader(inputStream));
        for (String s = in.readLine(); s != null; s = in.readLine()) {
          System.console().writer().println(name + ": " + s);
        }
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }

  public static void main(String[] args) throws Exception {
    String command = "psql -U archadm arch";
    final Process child = Runtime.getRuntime().exec(command);
    new ReadingThread(child.getInputStream(), "out").start();
    new ReadingThread(child.getErrorStream(), "err").start();
    BufferedWriter out = new BufferedWriter(
        new OutputStreamWriter(child.getOutputStream()));
    out.write("\\h");
    out.newLine();
    out.flush();
    out.write("\\q");
    out.newLine();
    out.flush();
  }

}

newLine () - то же самое, что и запись разделителя строки платформы. Как и следовало ожидать, он печатает справку, начинающуюся с «out:», затем завершает работу. Если я не отправлю «\ q», он не выйдет (очевидно), но все равно выдает справку. Использование «\ r \ n» или «\ r» вместо разделителя строк платформы не очень хорошая идея для меня, потому что такие утилиты командной строки обычно обнаруживают, что они не получают ввод с терминала, и предполагают это в родном текстовом формате (подумайте «psql

0 голосов
/ 08 февраля 2011

Вы также можете попробовать посмотреть на этот API

http://download.oracle.com/javase/6/docs/api/java/io/Console.html

По своему опыту я никогда не пытался делать что-то большее, чем запуск одного процесса из Process API.Кажется, что вы хотите ввести несколько команд, я думаю, этот API может позволить вам сделать это.

РЕДАКТИРОВАТЬ: нашел учебник по нему, чтобы помочь вам в дальнейшем.http://download.oracle.com/javase/tutorial/essential/io/cl.html

Надеюсь, это поможет,

0 голосов
/ 08 февраля 2011

А как насчет out.write((char) 13)? Смотрите эту Википедию статью. У меня недостаточно кода, чтобы проверить это для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...