Reputation: 4410
I have an external program Otter that gets as parameter some filename and creates an output file, also specified as parameter. So for example if my input is "proof.in" and I want my output to be placed in the "proof.out" file, I run the following command in the terminal:
otter <proof.in >proof.out
The "proof.in" file must be in the same file as the otter executable.
The problem is that I need this functionality from Java so in my Java code I do the following:
java.lang.Runtime.getRuntime().exec("otter <proof.in >proof.out")
but after this line the whole UI is frozen and nothing happens and no output file is generated.
Could anyone show me where I got it wrong??
Thanks in advance, Tamash
Upvotes: 0
Views: 4646
Reputation: 1
If you only want to run the program, do always remember this:
Process p=Runtime.getRuntime().exec ("cmd /c dir");
p.waitFor();
Upvotes: 0
Reputation:
Here is a link to another question with a very detailed answer on how to do this correctly in an async way with threads. This is the only way to not block your main thread and hang your GUI.
private class ProcessResultReader extends Thread
{
final InputStream is;
final String type;
final StringBuilder sb;
ProcessResultReader(@Nonnull final InputStream is, @Nonnull String type)
{
this.is = is;
this.type = type;
this.sb = new StringBuilder();
}
public void run()
{
try
{
final InputStreamReader isr = new InputStreamReader(is);
final BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null)
{
this.sb.append(line).append("\n");
}
}
catch (final IOException ioe)
{
System.err.println(ioe.getMessage());
throw new RuntimeException(ioe);
}
}
@Override
public String toString()
{
return this.sb.toString();
}
}
then you use the above class like so
try
{
final Process p = Runtime.getRuntime().exec(String.format("cmd /c %s", query));
final ProcessResultReader stderr = new ProcessResultReader(p.getErrorStream(), "STDERR");
final ProcessResultReader stdout = new ProcessResultReader(p.getInputStream(), "STDOUT");
stderr.start();
stdout.start();
final int exitValue = p.waitFor();
if (exitValue == 0)
{
System.out.print(stdout.toString());
}
else
{
System.err.print(stderr.toString());
}
}
catch (final IOException e)
{
throw new RuntimeException(e);
}
catch (final InterruptedException e)
{
throw new RuntimeException(e);
}
Upvotes: 0
Reputation: 121710
This is normal: you are attempting to launch a command normally issued by a shell.
Here, <proof.in
and >proof.out
are taken as literal arguments to the otter
executable, and not shell redirections. But seeing the home page for this tool, it will not work: it expects data on stdin, which the redirect normally provides.
You need to launch this command via a shell, and preferably using a process builder:
final ProcessBuilder pb = new ProcessBuilder("/bin/sh", "-c", "otter <proof.in >proof.out");
final Process p = pb.start();
etc etc.
You should also ensure, of course, that the program runs from the correct directory -- fortunately, ProcessBuilder
also allows you to do that.
Upvotes: 5
Reputation: 547
You could see what is happening when you execute your command:
try {
Process p=Runtime.getRuntime().exec ("cmd /c dir");
InputStream is = p.getInputStream();
BufferedReader br = new BufferedReader (new InputStreamReader (is));
String aux = br.readLine();
while (aux!=null) {
System.out.println (aux);
aux = br.readLine();
}
}
catch (Exception e) {
e.printStackTrace();
}
with this code.
Upvotes: -1