Выполнить внешний процесс из Java. Получил вывод после завершения процесса, но нужно до завершения - PullRequest
2 голосов
/ 19 июля 2011

Почему я получаю вывод процесса после его завершения? Мне нужно, чтобы процесс выводился «вживую», пока он запущен, а не после его завершения. Я хотел бы запустить такой процесс, как jboss, который регистрирует стандартный вывод, поэтому мне нужна эта информация вовремя, а не после завершения процесса. Спасибо за ответы.

Вот мой код:

        try {
        process = processBuilder.start();
        processOutput = process.getOutputStream();
        processInput = process.getInputStream();
        processReader = new BufferedReader(new InputStreamReader(
                processInput));
        processWriter = new BufferedWriter(new OutputStreamWriter(
                processOutput));

        while ((line = processReader.readLine()) != null) {
            System.out.println(line);
          }
        processReader.close();

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

Расширение:

Итак, я хотел бы запустить внешнюю программу из плагина Eclipse с помощью кнопки. Когда я нажимаю кнопку, запускается программа, и вывод внешней программы возвращается к консоли. Когда я нажимаю до остановки, программа останавливается. Итак, вот как я делаю пример создателя процесса. И я создал пример класса для тестирования компоновщика процессов без запуска всего проекта плагина в каждой модификации.

Вот мой экземпляр компоновщика процессов, который реализует Runnable:

@Override
public void run() {
    List<String> command = new ArrayList<String>();
    command.add(serverPath);
    command.add(String.valueOf(count));
    command.add(filePath);
    processBuilder = new ProcessBuilder(command);
    processBuilder.redirectErrorStream(true);

    try {
        process = processBuilder.start();
        processOutput = process.getOutputStream();
        processInput = process.getInputStream();
        processReader = new BufferedReader(new InputStreamReader(
                processInput));
        processWriter = new BufferedWriter(new OutputStreamWriter(
                processOutput));

        System.out.println(process.waitFor());
        while ((line = processReader.readLine()) != null) {
            System.out.println(line);

        }
        processReader.close();

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

Параметры поступают в конструктор. И вот экземпляр:

public static void main(String[] args) throws Exception

{

 SimulationProcess smp = new SimulationProcess(count, "file",
            "program_name");
    smp.run();

}

Ответы [ 2 ]

4 голосов
/ 19 июля 2011

Есть несколько вещей, которые вы можете попробовать решить:

a) Создайте тестовую программу и запустите ее с кодом выше, чтобы убедиться, что вы можете правильно ее прочитать.Например:

public static void main(String[] args) {
  for(;;) {
    try {
      Thread.sleep(5000);
      System.out.println("Test output");
    } catch(InterruptedException e) {
      // Ignore
    }

  }
}

b) Убедитесь, что вы обрабатываете поток ошибок процесса - процесс может заблокироваться, если вы не обработаете поток ошибок.Посмотрите на этот сайт , чтобы узнать о том, чего следует избегать при использовании Java ProcessBuilder или Runtime.exec () - он включает в себя реализацию StreamGobbler, которая выбрасывает все данные в поток, который вас не волнуето.

в) Попробуйте использовать System.out.flush() - возможно, ваш вывод буферизирован.

РЕДАКТИРОВАТЬ: Спасибо за обновление.Ваша проблема здесь:

System.out.println(process.waitFor()); // Waits for the process to exit.
while ((line = processReader.readLine()) != null) {
    System.out.println(line);
}

Если вы удалите waitFor (), он продолжит печатать, пока поток не закроется.Поток должен закрываться, только если процесс умирает.Вы должны поставить waitFor() после цикла?

0 голосов
/ 19 июля 2011

Возможно, ваш вывод не содержит символа новой строки, поэтому ваш цикл while ничего не сделает, пока процесс не будет завершен.

Попробуйте использовать другой метод чтения, который не ожидает символа новой строки, например:

char[] cbuf = new char[10];
while(processReader.read(cbuf) != -1)
{
  System.out.print(cbuf);
}
...