22 сентября 2010 г.

Запуск внешней программы на Java

Удобным средством для запуска внешних программ из java-кода является класс ProcessBuilder. С помощью экземпляра этого класса можно указать программу для запуска, параметры её запуска, переменные окружения, рабочий каталог и включить перенаправление потока вывода ошибок на стандартный вывод.

Ниже приведу простой пример использования ProcessBuilder с комментариями.

import java.io.*;

public class ExternalProgramLauncher {

 public static void main(String[] args) 
  throws IOException, InterruptedException {

  // указываем в конструкторе ProcessBuilder,
  // что нужно запустить программу ls с параметрами -l /dev
  ProcessBuilder procBuilder = new ProcessBuilder("ls","-l","/dev");  
  
  // перенаправляем стандартный поток ошибок на
  // стандартный вывод
  procBuilder.redirectErrorStream(true);
 
  // запуск программы
  Process process = procBuilder.start();
 
  // читаем стандартный поток вывода
  // и выводим на экран
  InputStream stdout = process.getInputStream();
  InputStreamReader isrStdout = new InputStreamReader(stdout);
  BufferedReader brStdout = new BufferedReader(isrStdout);

  String line = null;
  while((line = brStdout.readLine()) != null) {
   System.out.println(line);
  }
  
  // ждем пока завершится вызванная программа
  // и сохраняем код, с которым она завершилась в 
  // в переменную exitVal
  int exitVal = process.waitFor();
 }
}

Часть вывода программы:
итого 0
crw-rw---- 1 root   root       10,  54 Сен 17 12:38 autofs
crw-rw---- 1 root   root       10,  63 Сен 18 00:38 binder
drwxr-xr-x 2 root   root           520 Сен 21 15:35 block
drwxr-xr-x 2 root   root            60 Сен 21 15:35 bsg
drwxr-xr-x 3 root   root            60 Сен 18 00:38 bus

В данном примере не требуется редактировать переменные окружения, указывать полный путь к программе ls или рабочий каталог, т.к. java по умолчанию имеет доступ к системной переменной окружения PATH, которая содержит каталог /bin, но если вы запускаете какую-то программу из какого-то своего каталога, то что-либо из вышеперечисленного сделать придется.

Обязательно (!) следует вызывать метод process.waitFor(), иначе ваша программа может завершиться до того как завершится внешняя, и прихлопнет этот запущенный ею процесс.

Простой и понятный пример, демонстрирующий работу с переменными окружения и установку рабочего каталога приведен в документации к Java Platform SE 6:

ProcessBuilder pb = new ProcessBuilder("myCommand", "myArg1", "myArg2");
// получаем окружение
Map<String, String> env = pb.environment();
// добавляем новую переменную VAR1 со значением myValue
env.put("VAR1", "myValue");
// удаляем переменную OTHERVAR
env.remove("OTHERVAR");
// добавляем переменную VAR2 используя значение 
// переменной VAR1
env.put("VAR2", env.get("VAR1") + "suffix");
// устанавливаем рабочий каталог
pb.directory(new File("myDir"));
// запускаем программу
Process p = pb.start();

2 комментария:

  1. Добрый день! Скажите, а как можно запустить стороннюю программу
    а. под Linux в Java
    б. ,которая была написана под windows с использованием .Net

    короче, все тоже самое, что у Вас, только приложение Windows с двумя аргументами (входной/выходной) файл.

    Заранее огромное спасибо, если есть возможность, ответьте на мой e-mail...(antonermak@inbox.ru)

    Честно говоря, уже все перепробовал...

    ОтветитьУдалить
  2. Спасибо, подробно и доходчиво ...

    ОтветитьУдалить