2010-05-20 6 views
1

Я пытаюсь выполнить программу из кода Java. Вот мой код:Выполнение внешней программы из 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 (если это помогает).

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

Спасибо,

+0

Это продолжение из http://stackoverflow.com/questions/2874591/execute-external-program-from-java/2874687#2874687. – mdma

ответ

2

Вы не можете перенаправить вывод в файл и читать вывод в 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(), поскольку выполнение процесса является асинхронным, так что вы должны ждать его завершения.
  • Данные считываются из файла, а не с выхода процесса (так как это будет пустой.)
+0

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

+0

Я бы сделал имя файла в вашей команде и при создании абсолютного FileInputStream, так что вы не столкнетесь с проблемами рабочих каталогов. – mdma

+0

@Saurabh Как предполагают, процесс заканчивается раньше, потому что вы не добавили p.waitFor(). –

1

Ответ от 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

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

0

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

  • 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 

из Баш оболочки подскажет вы получите сообщение об ошибке, говорящее о том, что команда не может быть найдена и пустой «something.txt» файлом. (Вы не увидите сообщение об ошибке в своем приложении Java, потому что оно записывается в stderr, и вы его не захватываете.) Причина, по которой создается пустой файл «something.txt», заключается в том, что он открывается оболочкой перед он пытается разблокировать и выполнить «исполняемый файл».

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

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

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

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

+0

Это хорошая перефразировка комментариев в моем ответе! :) – mdma

+0

@mdma - Я думаю, что я делаю больше, чем это ... –

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