2012-01-05 6 views
0

У меня есть внешняя программа Otter, которая получает в качестве параметра некоторое имя файла и создает выходной файл, также указанный как параметр. Так, например, если мой вход «proof.in», и я хочу, чтобы мой выход будет помещен в файл «proof.out», я запускаю следующую команду в терминале:Выполнение внешней программы через терминал в Java

otter <proof.in >proof.out 

В «доказательство. в "файл должен быть в том же файле, что и исполняемый файл выдра.

Проблема заключается в том, что мне нужна эта функциональность от Java, так в моем коде Java я сделать следующее:

java.lang.Runtime.getRuntime().exec("otter <proof.in >proof.out") 

, но после этой линии весь пользовательский интерфейс замораживается, и ничего не происходит, и выходной файл не генерируется.

Может ли кто-нибудь показать мне, где я ошибся?

Спасибо заранее, Тамаш

+0

Ожидает ли ваша программа какой-то пользовательский ввод? Если это так, он будет ждать ввода. –

+0

Возможный дубликат [Выполнение другой java-программы из нашей java-программы] (http://stackoverflow.com/questions/7770094/executing-another-java-program-from-our -java-program) –

ответ

5

Это нормально: вы пытаетесь запустить команду, обычно выдаваемую оболочкой.

Здесь <proof.in и >proof.out принимаются как литературные аргументы в otter исполняемый файл, а не перенаправление оболочки. Но, видя домашнюю страницу этого инструмента, он не будет работать: он ожидает данные по stdin, которые обычно предоставляет перенаправление.

Вам необходимо запустить эту команду через оболочку, и предпочтительно с использованием процесса строитель:

final ProcessBuilder pb = new ProcessBuilder("/bin/sh", "-c", "otter <proof.in >proof.out"); 
final Process p = pb.start(); 

и т.д. и т.п.

Вы должны также обеспечить, конечно, что программа работает с правильным каталог - к счастью, ProcessBuilder также позволяет это сделать.

+0

+1 Для исследования инструмента –

+0

Фантастический сэр! Большое спасибо! –

-1

Вы могли видеть, что происходит, когда вы выполняете вашу команду:

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(); 
    } 

с этим кодом.

0

Вот link на другой вопрос с очень подробным ответом на то, как это сделать правильно асинхронно с потоками. Это единственный способ не блокировать основной поток и повесить графический интерфейс.

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(); 
    } 
} 

затем использовать выше класс, как так

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); 
} 
0

Если вы только хотите, чтобы запустить программу, вы всегда помните: Process p=Runtime.getRuntime().exec ("cmd /c dir"); p.waitFor();

Смежные вопросы