Подтвердить что ты не робот

Перенаправить процесс вывода на стандартный вывод

Я хотел бы выполнить foo.bat из программы Groovy и получить полученный результат процесса, перенаправленный на stdout. Пример кода Java или Groovy был бы в порядке.

foo.bat может занять несколько минут и генерировать много результатов, поэтому я хотел бы видеть результат сразу же после его создания, вместо того, чтобы ждать, пока процесс завершится, прежде чем увидеть весь вывод на один раз.

4b9b3361

Ответ 1

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

class StreamGobbler extends Thread {
    InputStream is;

    // reads everything from is until empty. 
    StreamGobbler(InputStream is) {
        this.is = is;
    }

    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(line);    
        } catch (IOException ioe) {
            ioe.printStackTrace();  
        }
    }
}

Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("javac");
//output both stdout and stderr data from proc to stdout of this process
StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream());
StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream());
errorGobbler.start();
outputGobbler.start();
proc.waitFor();

Ответ 2

Просто перенаправить весь поток на стандартный вывод с помощью метода inheritIO(). Это приведет к выводу вывода на стандартный вывод процесса, с которого выполняется эта команда.

ProcessBuilder pb = new ProcessBuilder("command", "argument");
pb.directory(new File(<directory from where you want to run the command>));
pb.inheritIO();
Process p = pb.start();
p.waitFor();

Существуют и другие методы, например, как указано ниже. Эти индивидуальные методы помогут перенаправить только требуемый поток.

    pb.redirectInput(Redirect.INHERIT)
    pb.redirectOutput(Redirect.INHERIT)
    pb.redirectError(Redirect.INHERIT)

Ответ 3

Если вы хотите сделать это с большим количеством Groovy и меньше java, это напечатает каждую строку, как это происходит:

def cmd = "./longRunningProcess"

def process = cmd.execute()
process.in.eachLine { line -> println line }

В качестве альтернативы, если вы хотите видеть как stdout, так и stderr

def cmd = "./longRunningProcess"

def process = cmd.execute()
process.waitForProcessOutput( System.out, System.err )

Ответ 4

Здесь что-то немного проще, если вы просто пытаетесь захватить вывод простой команды. Вам нужно будет использовать потоки, такие как jitter, если вы хотите обрабатывать параллельно или если ваша команда принимает stdin или генерирует stderr.

Используйте буферизованную копию (например this), если вы получаете много результатов.

import java.io.*;
public class test {
  static void copy(InputStream in, OutputStream out) throws IOException {
    while (true) {
      int c = in.read();
      if (c == -1) break;
      out.write((char)c);
    }
  }

  public static void main(String[] args) throws IOException, InterruptedException {
    String cmd = "echo foo";
    Process p = Runtime.getRuntime().exec(cmd);
    copy(p.getInputStream(), System.out);
    p.waitFor();
  }
}

Ответ 5

Следующий Groovy код выполнит foo.bat и отправит вывод в stdout:

println "foo.bat".execute().text

Ответ 6

Асинхронный способ его достижения.

void inputStreamToOutputStream(final InputStream inputStream, final OutputStream out) {
    Thread t = new Thread(new Runnable() {

        public void run() {
            try {
                int d;
                while ((d = inputStream.read()) != -1) {
                    out.write(d);
                }
            } catch (IOException ex) {
                //TODO make a callback on exception.
            }
        }
    });
    t.setDaemon(true);
    t.start();
}

{
    Process p = ...;
    inputStreamToOutputStream(p.getErrorStream(), System.out);
    inputStreamToOutputStream(p.getInputStream(), System.out);
}

Ответ 7

VerboseProcess от jcabi-log может помочь вы:

String output = new VerboseProcess(new ProcessBuilder("foo.bat")).stdout();