Выполните внешнюю программу от Java

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

public static void main(String argv[]) {
    try {
      String line;
      Process p = Runtime.getRuntime().exec(
          "/bin/bash -c ls > OutputFileNames.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.

Если я удаляю "> OutputFileNames.txt" от getRuntime().exec() метод, все имена файлов печатаются на консоли очень хорошо. Но мне нужен он, чтобы быть распечатанным в файл.

Кроме того, если я изменяю команду на:

Process p = Runtime.getRuntime().exec(
    "cmd \c dir > OutputFileNames.txt"); 

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

Я прочитал другие сообщения для выполнения другого приложения от Java, но ни один, казалось, не касался моей проблемы.

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

Спасибо,

7
задан paxdiablo 20 May 2010 в 14:24
поделиться

3 ответа

Чтобы перенаправление работало так, как написано, вам нужно сделать следующее:

Process p = Runtime.getRuntime().exec(
      new String[]{"/bin/bash", "-c", "ls > OutputFileNames.txt"});

Проблема, с которой вы столкнулись, - это простой способ, которым Runtime.exec (String) разбивает команду строка в аргументы.

Если бы вы запускали эту команду (как есть) в приглашении оболочки, вам пришлось бы ввести ее как:

$ /bin/bash -c "ls > OutputFileNames.txt"

, потому что параметр «-c» для «bash» требует командной строки для порожденного оболочка как единственный аргумент оболочки. Но если вы поместите голые кавычки в строку Java, метод Runtime.exec (String) по-прежнему будет неправильно разбивать. Единственное решение - предоставить аргументы команды в виде массива.

8
ответ дан 7 December 2019 в 01:17
поделиться

Проблема возникает потому, что стандартный вывод процесса направляется в файл, поэтому java Process не может собрать вывод.

Если вы хотите, чтобы вывод записывался в файл и был доступен для чтения в java, то у вас есть два варианта:

  1. Сохранить перенаправление на месте, а затем прочитать листинг из OutputFile.txt в java, например, используя new FileReader("OutputFile.txt"). Обратите внимание, что exec() является асинхронным и может вернуться до того, как процесс закончит запись в файл, поэтому вам нужно будет дождаться выхода процесса, используя Process.waitFor().
  2. Уберите перенаправление и прочитайте листинг непосредственно в java (как вы это делаете). Затем вы можете записать этот листинг в файл с помощью FileWriter.

Суть в том, что вы не можете одновременно использовать редирект и читать вывод из Process - либо одно, либо другое.

EDIT: Ваши комментарии указывают на то, что 1) является предпочтительным подходом. Это позволит записать вывод в файл (используя оболочку ОС), который вы затем прочитаете из java, когда процесс завершится.

1
ответ дан 7 December 2019 в 01:17
поделиться

Пара вещей, на которые стоит обратить внимание.

  • проверьте, в каком каталоге выполняется ваша программа (таким же образом запустив pwd ), затем проверьте, есть ли у вас права на запись в этот каталог.
  • проверьте, существует ли этот файл OutputFileNames.txt (и проверьте права доступа).
  • если файл действительно существует, удалите его и запустите повторно, чтобы увидеть, будет ли он воссоздан заново, и посмотрите на содержимое, если оно существует.
  • попробуйте использовать команду "/ bin / bash -c 'ls> OutputFileNames.txt'" - возможно, что вывод bash будет , а не то же, что и вывод ls (в вашем примере перенаправление может применяться к bash , а не к ls ).
1
ответ дан 7 December 2019 в 01:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: