Erro padrão de drenagem em Java
-
09-06-2019 - |
Pergunta
Ao iniciar um processo de Java, tanto o stderr quanto o stdout podem bloquear a saída se eu não ler os pipes.Atualmente tenho um thread que lê proativamente um e o thread principal bloqueia o outro.
Existe uma maneira fácil de unir os dois fluxos ou fazer com que o subprocesso continue sem perder os dados no stderr?
Solução
Defina a propriedade redirectErrorStream no ProcessBuilder para enviar a saída stderr para stdout:
ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);
Você deve então criar um thread para lidar com o fluxo do processo, algo como o seguinte:
Process p = builder.start();
InputHandler outHandler = new InputHandler(p.getInputStream());
Onde InputHandler é definido como:
private static class InputHandler extends Thread {
private final InputStream is;
private final ByteArrayOutputStream os;
public InputHandler(InputStream input) {
this.is = input;
this.os = new ByteArrayOutputStream();
}
public void run() {
try {
int c;
while ((c = is.read()) != -1) {
os.write(c);
}
} catch (Throwable t) {
throw new IllegalStateException(t);
}
}
public String getOutput() {
try {
os.flush();
} catch (Throwable t) {
throw new IllegalStateException(t);
}
return os.toString();
}
}
Alternativamente, basta criar dois InputHandlers para InputStream e ErrorStream.Saber que o programa irá bloquear se você não os ler é 90% da batalha :)
Outras dicas
Basta ter dois threads, um lendo do stdout e outro do stderr?