Выполнить внешнюю программу из Java - PullRequest
1 голос
/ 20 мая 2010

Я пытаюсь выполнить программу из кода Java. Вот мой код:

public static void main(String argv[]) {
    try {
      String line;
      Process p = Runtime.getRuntime().exec(new String[]{
          "/bin/bash", "-c", "executable -o filename.txt"});
      BufferedReader input = new BufferedReader(
          new InputStreamReader(p.getInputStream()));
      while ((line = input.readLine()) != null) {
        System.out.println(line);
      }
      input.close();
    } catch (Exception err) {
      err.printStackTrace();
    }
}

Моя ОС - Mac OS X 10.6.

Теперь исполняемый файл, который я пытаюсь запустить, должен выплевывать вывод в filename.txt. Если я беру эту команду и запускаю ее на терминале, она работает нормально, и также заполняется файл filename.txt. Но из моей java-программы файл не создан.

если вместо этого я использую исполняемый файл> filename.txt, то файл filename.txt будет создан, но пуст. Не уверен, что здесь не так. Исполняемый файл, который я пытаюсь запустить, это Xtide (если это помогает).

Я был бы очень признателен за любую помощь.

Спасибо

Ответы [ 3 ]

2 голосов
/ 20 мая 2010

Вы не можете перенаправить вывод в файл и прочитать вывод в Java. Это одно или другое. То, что вы хотите, это:

      Process p = Runtime.getRuntime().exec(new String[]{
          "/bin/bash", "-c", "executable -o filename.txt"});
      p.waitFor();
      BufferedReader input = new BufferedReader(
          new InputStreamReader(new FileInputStream("filename.txt")));
      while ((line = input.readLine()) != null) {
        System.out.println(line);
      }

Основные изменения:

  • p.waitFor(), поскольку выполнение процесса асинхронно, поэтому вам нужно дождаться его завершения.
  • Данные читаются из файла, а не из выходных данных процесса (поскольку он будет пустым).
1 голос
/ 20 мая 2010

Ответ от mdma работает (и я проголосовал за него), но вы также можете рассмотреть версию, в которой вы читаете поток вывода непосредственно из executable:

Process p = Runtime.getRuntime().exec(new String[]{
          "/bin/bash", "-c", "executable"});
p.waitFor();
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream())_;
while ((line = input.readLine()) != null) {
    System.out.println(line);
}
0 голосов
/ 21 мая 2010

Поправьте меня, если я ошибаюсь, но симптомы таковы:

  • exec("/usr/bash", "-c", "executable > filename.txt") создает пустой файл.
  • exec("/usr/bash", "-c", "executable -o filename.txt") не создает файл.
  • Один или оба из вышеперечисленных дает код выхода 255, когда вы смотрите на него.
  • Когда вы запускаете команду из командной строки как executable -o filename.txt или executable > filename.txt, она работает как положено.

В свете вышесказанного, я думаю, что наиболее вероятной причиной является то, что /bin/bash не находит executable при запуске его из Java. Тот факт, что в первом примере создается пустой файл, означает, что /bin/bash что-то делает. Но если вы попытаетесь запустить

$ unknown-command > somefile.txt

из приглашения оболочки bash вы получите сообщение об ошибке, в котором говорится, что команда не может быть найдена , и пустой файл "thing.txt ". (Вы не увидите сообщение об ошибке в вашем Java-приложении, потому что оно записывается в stderr, и вы его не захватываете.) Причина, по которой создается пустой файл "thing.txt ", заключается в том, что оно открывается оболочкой * За 1026 * до он пытается форкнуть и выполнить "исполняемый файл".

Если это проблема , то простое решение - использовать абсолютный путь к исполняемому файлу.

Кроме того, если вы не выполняете перенаправление командной строки или другую магию оболочки, нет необходимости запускать исполняемый файл в новом экземпляре bash. Скорее просто сделайте это:

Process p = Runtime.getRuntime().exec("executable", "-o", filename.txt");

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...