Controlar um programa externo pelo Java

Caros,

Estou com o seguinte problema:

Tenho um programa feito em C++ que está preparado para trabalhar ou linha de comando. Ou seja, para trabalhar escrevendo dados na tela e esperando que outros comandos sejam enviados para ele.
Este programa está preparado para trabalhar da seguinte maneira: Escreve uma string na tela, lê um caracter. Escreve uma string na tela, lê um caracter…

Eu quero controlar esse programa através do Java. Ou seja, quero que o Java execute-o e, enquanto ele é executado, leia as saídas do meu programa em C++ e, de acordo com as saídas, envie um comando diferente.

Eu tentei fazer isso da seguinte maneira:

Process p = new ProcessBuilder("programa.exe").start();
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));

String line = "";
while(true) {
	while ((line = br.readLine()) != null) {
		System.out.println(line);
		break;
	}
	if (line.equals("frase")) bw.write('c');
	else break;
}

O problema é o seguinte: o Java espera o “programa.exe” terminar para pegar suas saídas. Só que eu não posso esperar o programa terminar, já que eu quero enviar comandos para ele.

Como eu posso resolver esse problema?

Leia esse tópico: http://www.guj.com.br/posts/list/213361.java#1086652

Um pouco mais abaixo, mostro outra classe que faz o mesmo que o StreamGobbler: http://www.guj.com.br/posts/list/213361.java#1087285

Senhores, consegui resolver o problema. Não estou com o código aqui mas vou fazer o possível para reproduzi-lo

Process p = new ProcessBuilder("programa.exe").start();
InputStream in = p.getInputStream();
OutputStream out = p.getOutputStream();

char c;
String entrada = "";
while(true) {
	if (in.available() > 0) {
                  c = (char) in.read();
                  entrada += c;
                  if (c == ';') break;
        }
}

System.out.println("Entrada: " + entrada);
System.out.println("Saída: " + 'f');
out.write(new byte[] {'f', '\n'});
out.flush();

Esse código funciona. Acho que consegui reproduzir o programa bem aqui, apesar de estar sem o editor. Algumas diferencas entre este programa e o anterior:

1 - O método readline parece que fica travado esperando o programa chamado terminar de ser executado para que leia o que tem dentro. Não sei se é bem isso, mas é a impressão que eu tenho. O ponto e vígula age como um caracter delimitador, que indica o fim da frase que o meu programa em Java lê do programa em c++;
2 - Na hora de escrever eu preciso usar o método flush() alem do método write(), senão ele não escreve o meu caracter nunca. O ‘\n’ do final é por causa do cin, dentro do próprio c++, que só lê o caracter da frase depois que o enter é pressionado.

Se você adicionar alguns if’s a esse programa e um while por fora, pode controlar qualquer programa que trabalhe a base de entradas do teclado.

Obrigado pela ajuda mais uma vez, pessoal.

Ao utilizar Runtime.getRuntime().exec(“meu programa”);

exec retorna um objeto do tipo Process e por ele vc pode ler a saída (e mais algumas coisas).

http://download.oracle.com/javase/6/docs/api/java/lang/Runtime.html

http://download.oracle.com/javase/6/docs/api/java/lang/Process.html

Good luck