Java Runtime.exec () асинхронный вывод - PullRequest
5 голосов
/ 13 октября 2011

Я хотел бы получить вывод из длительной команды оболочки, поскольку она доступна, а не ждать завершения команды.Мой код запускается в новом потоке

Process proc = Runtime.getRuntime().exec("/opt/bin/longRunning");
InputStream in = proc.getInputStream();
int c;
while((c = in.read()) != -1) {
    MyStaticClass.stringBuilder.append(c);
}

Проблема в том, что моя программа в / opt / bin / longRunning должна завершиться до того, как InputStream будет назначен и прочитан.Есть ли хороший способ сделать это асинхронно?Моя цель - чтобы ajax-запрос возвращал текущее значение MyStaticClass.stringBuilder.toString () каждую секунду или около того.

Я застрял на Java 5, fyi.

Спасибо!W

Ответы [ 5 ]

7 голосов
/ 13 октября 2011

Попробуйте с Apache Common Exec . Он имеет возможность асинхронно выполнять процесс, а затем «качать» вывод в поток. Проверьте Javadoc для получения дополнительной информации

1 голос
/ 13 октября 2011

Вы написали программу, которую звоните?Если это так, попробуйте сбросить вывод после записи.Текст может застрять в буфере и не попасть в вашу Java-программу.

Я использую этот код для этого, и он работает:

    Runtime runtime = Runtime.getRuntime();
    Process proc = runtime.exec(command);
    BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));

    while (true) {

        // enter a loop where we read what the program has to say and wait for it to finish
        // read all the program has to say
        while (br.ready()) {
            String line = br.readLine();
            System.out.println("CMD: " + line);
        }

        try {
            int exitCode = proc.exitValue();
            System.out.println("exit code: " + exitCode);
            // if we get here then the process finished executing
            break;
        } catch (IllegalThreadStateException ex) {
            // ignore
        }

        // wait 200ms and try again
        Thread.sleep(200);

    }
1 голос
/ 13 октября 2011

Поместите чтение в новую ветку:

new Thread() {
    public void run() {
        InputStream in = proc.getInputStream();
        int c;
        while((c = in.read()) != -1) {
            MyStaticClass.stringBuilder.append(c);
        }
    }
}.start();
1 голос
/ 13 октября 2011

Runtime.getRuntime (). Exec не ожидает завершения команды, поэтому вы должны сразу получить вывод.Может быть, вывод буферизуется, потому что команда знает, что она пишет в канал, а не в терминал?

0 голосов
/ 13 октября 2011

Попробуйте:

   try {  
         Process p = Runtime.getRuntime().exec("/opt/bin/longRunning");  
         BufferedReader in = new BufferedReader(  
                                    new InputStreamReader(p.getInputStream()));  
         String line = null;  
         while ((line = in.readLine()) != null) {  
         System.out.println(line);  }
...