Вывод разветвленного дочернего процесса на Java - PullRequest
3 голосов
/ 31 августа 2011

Я выполняю процесс cmd в собственных окнах из моей программы на Java.Я хочу иметь возможность просматривать вход и выход разветвленного процесса.Тем не менее, мне кажется, что я ничего не могу написать в нее из программы Java.

Когда я пытаюсь записать набор символов в командную строку в Windows, я ожидаю, что этораспечатать что-нибудь на экране - что угодно.Итак, если я дам ему бессмысленный мусор, то он должен напечатать, что он не понимает эту команду.

Однако после записи моей строки мусора в OutputStream дочернего процесса в следующем коде:

Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("cmd");
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
PrintWriter out = new PrintWriter(process.getOutputStream());
String line = null;
out.println("My Garbage String");
while((line = readLine()) != null)
    System.out.println(line);

программа останавливается там, где она говорит: while((line = readLine()) != null).

Итак, родительский процесс, очевидно, блокируется, пока дочерний процесс не получает некоторый ввод, не разблокирует и не отправляет этот ввод в родительский процесс.Но я даю дочернему процессу некоторый ввод, когда я что-то записываю в метод PrintWriter println(), не так ли?

ОБНОВЛЕНИЕ

Теперь, из-за некоторых ответов, которые мне дали, я решил уточнить, в чем заключается моя проблема.Я могу прочитать вывод из командной строки в порядке.Фактически, когда я впервые запускаю его, я получаю все те же выходные данные, которые вы обычно получаете, если вы наберете «cmd» в командной строке.

Например, возьмем следующий пример кода:

Process process = Runtime.getRuntime().exec("cmd");
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
PrintWriter out = new PrintWriter(process.getOutputStream());
String line = null;
do
{
    line = in.readLine();
    System.out.println(line);
}while(line!=null)

Вывод кода будет следующим:

Microsoft Windows XP [Версия 5.1.2600] (C) Copyright 1985-2001 Microsoft Corp.

Как видите, командная строка выводит мой родительский процесс на вывод.Но, запустив это в режиме отладки в моей IDE, я обнаружил, что он просто останавливается на строке line=in.readLine();.Таким образом, дочерний процесс блокируется, потому что больше нечего печатать.

Итак, когда я пытаюсь дать ему какой-то ввод, используя его свойство OutputStream, он не отвечает.Вместо этого программа блокируется там, где line=in.readLine();.

В ответ на то, что предложил один из авторов, упомянутая вами статья ( Когда Runtime.exec () не будет ), он только переходит к получению выходных данных из OutputStream и ErrorStream свойства.Здесь не упоминается, как я могу дать ему какой-либо ввод, кроме начальных параметров выполнения, которые задаются в виде массива при запуске Runtime.exec(args).

Для имитации того, что я хотел сделать изначально (т.е. дать ему случайный мусор и распечатать, что он не понимает команду), я мог бы просто набрать Runtime.getRumtime().exec("cmd /c random garbage); в моем коде и запустить его.Но это не то, что я хочу сделать.Я хочу общаться с командной строкой после того, как она уже начала свое выполнение.

В конечном счете, я хочу иметь возможность взаимодействовать с другой программой, которая обычно требует взаимодействия с ними после выполнения из программы Java.Тем не менее, если я могу сказать ему, что делать, только когда я укажу параметры его выполнения, то я не смогу взаимодействовать с отдельным процессом с использованием Java так, как я хочу.

Если кто-нибудь знает, как этого можно достичь, скажите, пожалуйста.Спасибо.

Ответы [ 5 ]

3 голосов
/ 31 августа 2011

StreamGobbler s способ пойти в Google для них. Они начинаются в новых темах и читают вывод.

Хорошая статья, описывающая, как вы их реализуете. Когда Runtime.exec () не будет

2 голосов
/ 31 августа 2011

Здесь у вас есть полный образец.Обратите внимание, что при запуске команды dir через выходной поток.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

class StreamGobbler extends Thread {
InputStream is;
String type;

StreamGobbler(InputStream is, String type) {
    this.is = is;
    this.type = type;
}

public void run() {
    try {
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);
        String line = null;
        while ((line = br.readLine()) != null)
            System.out.println(type + ">" + line);
    } catch (IOException ioe) {
        ioe.printStackTrace();
    }
}
}

public class GoodWindowsExec {
public static void main(String args[]) {


    try {
        String osName = System.getProperty("os.name");
        String[] cmd = new String[1];

        cmd[0] = "cmd.exe";

        Runtime rt = Runtime.getRuntime();

        Process proc = rt.exec(cmd);


        proc.getOutputStream().write("dir \n".getBytes());
        proc.getOutputStream().flush();
        // any error message?
        StreamGobbler errorGobbler = new StreamGobbler(
                proc.getErrorStream(), "ERROR");

        // any output?
        StreamGobbler outputGobbler = new StreamGobbler(
                proc.getInputStream(), "OUTPUT");

        // kick them off
        errorGobbler.start();
        outputGobbler.start();

        // any error???
        int exitVal = proc.waitFor();
        System.out.println("ExitValue: " + exitVal);
    } catch (Throwable t) {
        t.printStackTrace();
    }
}
}
1 голос
/ 31 августа 2011

Java-программа управляет вводом из process.getOutputStream (). Если вы хотите отправить данные в программу, вам нужно отправить их с Java.

0 голосов
/ 26 августа 2013

"Программа останавливается там, где она говорит while ((line = readLine ())! = Null)."

Ответ, вероятно, находится в отдельной проблеме Процесс Java с потоком ввода / вывода (из ответа Люка Вудворда):

.. циклы while ((line = readLine ())! = Null) выход только когда читатель, который читает из стандарта процесса выводит, возвращает конец файла. Это происходит только при выходе из процесса . Он не будет возвращать конец файла, если в настоящее время случается, что нет больше выхода из процесса. Вместо этого он будет ждать следующей строки вывода из процесса и не возвращать, пока не будет следующей строки.

Попробуйте использовать один поток для записи команд в process.getOutputStream (), а второй - для чтения process.getInputStream ().

0 голосов
/ 31 августа 2011

Вы путаете вещи. Прежде всего, текущее описание хаотично, и вы должны переписать его.

Во-вторых, выполните StreamGobbler, как указано в Farmor .

Что вы ожидаете от

out.println("My Garbage String"); 
while((line = readLine()) != null)
...

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

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