Pessoal… fiz uma aplicacao no linux e esta rodando normalmente… porem fui testar no windows… quando faco o comando Process.waitFor() ele trava … so com ctrl+al+del e matando a aplicacao…
Alguem pode me explicar? como contornar isso?
.
.
.
.
Runtime run = Runtime.getRuntime();
Process process=run.exec(teste);
process.waitFor();
.
.
.
Seria melhor se você colocasse um trecho maior de código para que a gente soubesse se tem I/O na parada. Mas de qualquer jeito há coisas que você precisa saber:
[quote=javadoc] The methods that create processes may not work well for special processes on certain native platforms, such as native windowing processes, daemon processes, Win16/DOS processes on Microsoft Windows, or shell scripts. The created subprocess does not have its own terminal or console. All its standard io (i.e. stdin, stdout, stderr) operations will be redirected to the parent process through three streams (getOutputStream(), getInputStream(), getErrorStream()). The parent process uses these streams to feed input to and get output from the subprocess. Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock.
The subprocess is not killed when there are no more references to the Process object, but rather the subprocess continues executing asynchronously. [/quote]
Ola Luca…
Entao… meu teste é um programa em C que gera um TXT … o pq deu estar usando o waitFor() é pq quero que termine a execucao para depois eu ler esse meu TXT… se eu tiro esse waitFor ele passa direto para outra tarefa… e nao acha o arquivo… pq ele vai ler esse arquivo…
Eu fiz uma telinha em SWING para achar o arquivo e apartir desse arquivo eu rodo o programa em C e gero o TXT…
entao esse exec(teste) pega o arquivo q eu entrei e gera o TXT…
Como eu poderia resolver isso sem precisar usar o waitFor()?
Obrigada
bom–>
eu coloquei new PrintStream(process.getInputStream()).start();
process.waitFor();
e funcionou…
Tem sim, é só criar um OutputStream que escreve num JTextArea…
[code]public class TextAreaOutputStream extends OutputStream {
private JTextArea txtArea;
public TextAreaOutputStream(JTextArea txtArea) {
if (txtArea == null)
throw new IllegalArgumentException(“Text area cannot be null!”);
this.txtArea = txtArea;
}
@Override public void write(int b) throws IOException {
byte[] ch = new byte[] {(byte)b};
txtArea.append(new String(ch));
}
@Override public void write(byte[] b, int off, int len) throws IOException {
String text = new String(b, off, len);
txtArea.append(text);
}
}[/code]
E depois no seu código, você faz:
StreamRedirector redirector = new StreamRedirector(new TextAreaOutputStream(seuTextArea), process.getInputStream());
Na verdade, você continua lendo linha a linha, mas ao invés de jogar para o TextArea direto, jogue para um StringBuilder. Só ao final, faça setTextArea.setText(stringBuilder.toString());
[quote=ViniGodoy]Tem sim, é só criar um OutputStream que escreve num JTextArea…
[code]public class TextAreaOutputStream extends OutputStream {
private JTextArea txtArea;
public TextAreaOutputStream(JTextArea txtArea) {
if (txtArea == null)
throw new IllegalArgumentException(“Text area cannot be null!”);
this.txtArea = txtArea;
}
@Override public void write(int b) throws IOException {
byte[] ch = new byte[] {(byte)b};
txtArea.append(new String(ch));
}
@Override public void write(byte[] b, int off, int len) throws IOException {
String text = new String(b, off, len);
txtArea.append(text);
}
}[/code]
E depois no seu código, você faz:
StreamRedirector redirector = new StreamRedirector(new TextAreaOutputStream(seuTextArea), process.getInputStream());
Funcionou com esse metodo… no linux funciona o waitFor() entao eu fazia assim:
BufferedInputStream bis = new BufferedInputStream(process.getInputStream());
int entrada = bis.read();
StringBuffer texto = new StringBuffer();
while (entrada != -1)
{
texto.append((char) entrada);
entrada = bis.read();
}
String saida =texto.toString();
Dai eu jogava na String saida a saida da execucao … e no windows nada de funcionar… estranhu ne ?
O Windows deixa que os processos gerenciem os buffers de saída. Por isso ele não pode eliminar o subprocesso invocado até que esse buffer tenha sido completamente lido ou que o processo que originou o subprocesso seja fechado.
Normalmente o SO gerencia automaticamente isso com os pipes, mas no seu caso, você pegou o controle do pipe para si.
Se isso é bom ou ruim? Bom, já não entendo tanto de SO assim para saber se essa decisão é mais ou menos acertada…
Mas, em ambos os casos, o waitFor funciona. O objetivo dele é esperar que o processo seja morto. Só que a decisão de quando isso ocorre é deixada para o SO (mais uma das coisas não tão multi-plataforma assim do Java). Em todo caso, acho que a solução da thread separada não só é mais interativa, como funciona em todos os sistemas operacionais que eu já testei (Windows, Linux, Mac).