Runtime.exec et gestion des flux
Bonjour amis développeurs,
Je me suis inspiré de ce tuto ici pour lancer un exécutable externe dans mon application.
Et ça marche... "Mais pourquoi poste t'il un sujet si ça marche?" vous demandez vous
En fait l'exécutable écris des choses dans la console au cours de son exécution, mais ces informations ne sont affichées qu'à la fin de l'exécution et j'aimerai qu'elles le soient au moment ou elles sont écrites par l'exécutable.
(J'affiche par exemple le temps restant estimé).
J'ai essayé avec la Classe ProccesConsumer de l'API d'adiGuba ici mais j'ai le même résultat.
Les lignes s'affichent uniquement a la fin de l'exécution du process.
Voici mes classes.
1. Process Launcher
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| class ProcessLauncher
{
final String inputFilePath;
Process process;
// Test API
// ProcessBuilder pb;
public ProcessLauncher(final String _inputFilePath)
{
inputFilePath = _inputFilePath;
}
public void exec(final boolean _waitForCompletion)
{
// On lance le processus
final Runtime runtime = Runtime.getRuntime();
try
{
process = runtime.exec(new String[] {
getExecutable().getAbsolutePath(),
"Name",
inputFilePath
});
// On ferme le flux STDIN du process (inutile)
process.getOutputStream().close();
// Ecoute stdout
new Thread(new DisplayStream(process.getInputStream(), System.out)).start();
// Ecoute stderr
new Thread(new ErrorStream(process.getErrorStream(), System.err)).start();
// TEST API
// final ProcessConsumer pc = new ProcessConsumer(process);
// pc.consume();
if (_waitForCompletion)
{
process.waitFor();
}
}
catch (final IOException _e)
{
DialogUtils.showErrorMessageBox(_e.getMessage());
}
catch (final InterruptedException _e)
{
DialogUtils.showErrorMessageBox(_e.getMessage());
}
catch (final SystemModelerException _e)
{
DialogUtils.showErrorMessageBox(_e.getMessage());
}
}
public boolean isRunning()
{
if (process == null)
{
return false;
}
try
{
process.exitValue();
return false;
}
catch (final Throwable t)
{
}
return true;
}
public Integer getExitValue()
{
try
{
return (process != null ? Integer.valueOf(process.exitValue()) : null);
}
catch (final Throwable t)
{
return null;
}
}
/**
* Kills the running process
*/
public void killProcess()
{
try
{
if (process != null)
{
process.destroy();
}
}
catch (final Throwable t)
{
}
}
} |
2. ErrorStream : Pour la gestion du flux stderr
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| inal class ErrorStream implements Runnable
{
private final InputStream stream;
private final PrintStream printer;
ErrorStream(final InputStream _stream, final PrintStream _printer)
{
stream = _stream;
printer = _printer;
}
private BufferedReader getBufferedReader(final InputStream is)
{
return new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
}
@Override
public void run()
{
final BufferedReader br = getBufferedReader(stream);
String line = "";
try
{
final StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null)
{
// System.out.print(line);
printer.println(line);
sb.append(line + "\n");
}
if (sb.length() > 0)
{
DialogUtils.showErrorMessageBox(sb.toString());
}
}
catch (final IOException e)
{
Debug.logEvent(EventType.ERROR, e);
}
finally
{
stream.close();
}
}
} |
3.DisplayStream Pour la gestion du stdout
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| final class DisplayStream implements Runnable
{
private final InputStream stream;
private final PrintStream printer;
DisplayStream(final InputStream _stream, final PrintStream _printer)
{
stream = _stream;
printer = _printer;
}
private BufferedReader getBufferedReader(final InputStream is)
{
return new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
}
@Override
public void run()
{
final BufferedReader br = getBufferedReader(stream);
String line = "";
try
{
final StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null)
{
// System.out.println(line);
printer.println(line);
sb.append(line + "\n");
}
if (sb.length() > 0)
{
DialogUtils.showInformationMessageBox(sb.toString());
}
}
catch (final IOException e)
{
Debug.logEvent(EventType.ERROR, e);
}
finally
{
stream.close();
}
}
} |
J'ai vérifié que l'exécutable renvoie bien plusieurs lignes et le code me semble correspondre aux infos que j'ai regroupé du coup j'avoue que je n'ai pas d'idée de solution.
Merci pour vos futur idées.