От runtime.exec к ProcessBuilder

Перед JDK 5.0, единственным способом Ответвляемся процесс и запустить его на местном User Runtime заключалась в использовании Exec () Метод java.lang.Runtime класс. JDK 5.0 добавляет новый способ выполнения команды в отдельном процессе, через класс под названием ProcessBuilder. Вы можете найти ProcessBuilder в java.lang пакетом (например, среды выполнения и процесс). Этот совет обсуждает и сравнивает обоих подходов.

Если вы знакомы со средой класс, вы знаете, что оно также позволяет обнаружить использование памяти и добавить выключение крючок. Но, пожалуй, самым популярным использование классов до 5,0 было выполнить команду в отдельном процессе. Это было сделано с помощью одного из шести версий Exec () метод просмотра:

public Process exec(String command)
throws IOException
public Process exec(String command,
String[] envp)
throws IOException
public Process exec(String command,
String[] envp,
File dir)
throws IOException
public Process exec(String[] cmdarray)
throws IOExceptionjava
public Process exec(String[] cmdarray,
String[] envp)
throws IOException
public Process exec(String[] cmdarray,
String[] envp,
File dir)
throws IOException

Перед вызовом Exec () метод, можно указать команду и ее аргументы, настройки переменных окружения, а также рабочего каталога. Все версии метода возвращения java.lang.Process объект для управления созданной процесса. Это позволяет получить входной или выходной поток подпроцесс и статус выхода (помимо имеющейся информации).

Вот, например, DoRuntime, который показывает, как выполнить команду с оригинальным Время просмотра класс. Команда для запуска передается из командной строки.


   import java.io.*;

   import java.util.*;

   

   public class DoRuntime {

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



       if (args.length <= 0) {

         System.err.println("Need command to run");

         System.exit(-1);

       }



       Runtime runtime = Runtime.getRuntime();

       Process process = runtime.exec(args);

       InputStream is = process.getInputStream();

       InputStreamReader isr = new InputStreamReader(is);

       BufferedReader br = new BufferedReader(isr);

       String line;



       System.out.printf("Output of running %s is:"

           Arrays.toString(args));



       while ((line = br.readLine()) != null) {

         System.out.println(line);

       }



     }

    

Если вы запустите DoRuntime в Solaris так:

java DoRuntime ls

Вы получите вывод, который выглядит примерно следующим образом (в зависимости от содержимого каталога):

Output of running ls is:DoRuntime.class
DoRuntime.java

Linux пользователи также могут перейти в "Ls", как и команда, чтобы получить список каталогов.

На платформе Microsoft Windows, такие команды, как "Dir" являются внутренними для командного процессора, так что одним аргументом командной строки будет кавычки: "CMD / C Dir" (опять же, выход будет зависеть от содержимого каталога) .

>  java DoRuntime "cmd /c dir"
Output of running cmd /c dir is: ...
Directory of C:\...
07/15/2005  09:30 AM    <DIR>          .
07/15/2005  09:30 AM    <DIR>          ..
07/15/2005  09:30 AM             1,146 DoRuntime.class
07/15/2005  09:23 AM               724 DoRuntime.java
...

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

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

Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(command);
File file = new File(other directory);
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(command, null, file);

Второй параметр в вызове EXEC () определяются методом переменных окружения. Поскольку параметр является "нулевой", подпроцесс наследует настройку среды для текущего процесса.

Так что же случилось с таким подходом? Зачем создавать новый подход? Проблема заключается в том, что подход Runtime.exec не всегда позволяют легко настроить и вызывать подпроцессов. Новый класс ProcessBuilder упрощает вещи. С помощью различных методов в классе, вы можете легко изменить переменные среды для процесса, и начало этому процессу.

Вот простое использование ProcessBuilder, который дублирует функции DoRuntime Пример:


   import java.io.*;

   import java.util.*;

   

   public class DoProcessBuilder {

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



       if (args.length <= 0) {

         System.err.println("Need command to run");

         System.exit(-1);

       }



       Process process = new ProcessBuilder(args).start();

       InputStream is = process.getInputStream();

       InputStreamReader isr = new InputStreamReader(is);

       BufferedReader br = new BufferedReader(isr);

       String line;



       System.out.printf("Output of running %s is:"

          Arrays.toString(args));



       while ((line = br.readLine()) != null) {

         System.out.println(line);

       }



     }

    
> java DoProcessBuilder ls
Output of running ls is:DoProcessBuilder.class
DoProcessBuilder.java
DoRuntime.class
DoRuntime.java

Обратите внимание, что следующие две строки в DoRuntime:

Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(command);

были изменены на следующие строки в DoProcessBuilder:

Process process = new ProcessBuilder(command).start();

ProcessBuilder класс имеет два конструктора. Один конструктор принимает список для команды и ее аргументы. Другие конструктор принимает переменное количество аргументов строки.

public ProcessBuilder(List command)
public ProcessBuilder(String... command)

С ProcessBuilder, вы вызываете Start (), чтобы выполнить команду. До вызова Start (), вы можете управлять тем, как этот процесс будет создан. Если вы хотите, чтобы начать процесс в другом каталоге, вы не проходите файла в качестве аргумента командной строки. Вместо этого, вы устанавливаете рабочую директорию процесса строителя путем передачи файлов в каталоге () метод:

public ProcessBuilder directory(File directory)

Существует не очевидный метод тип сеттер в ProcessBuilder для установки переменных окружения. Вместо этого, вы получите карту с переменным через окружающую среду () метод, то можно манипулировать на карте:

ProcessBuilder processBuilder = new ProcessBuilder(command);
Map env = processBuilder.environment();
// manipulate env

Параметры для манипулирования окружающей среды включает в себя добавление переменных окружения с нанесенным () метод, и удаление их с удалить () метод. Например:

ProcessBuilder processBuilder = new ProcessBuilder(
command, arg1, arg2);
Map env = processBuilder.environment();
env.put("var1", "value");
env.remove("var3");

После задаются переменные среды и каталогов, начала звонка ():

processBuilder.directory("Dir");
Process p = processBuilder.start();

Вы также можете Clear () все переменные с окружающей средой и четко установить те, что вы хотите.

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

Вы можете получить исходный набор переменных среды, вызывая GETENV () Метод системы. Поймите, что не все платформы поддерживают изменение переменных окружения. Если вы попытаетесь изменить переменные окружения на платформе, который запрещает это, операция будет бросать или UnsupportedOperationException или IllegalArgumentException. Кроме того, при работе с менеджером безопасности, вам нужно RuntimePermission для "GETENV .*", в противном случае SecurityException будет брошен.

Помнить, что нельзя забывать Start () после вызова Настройка инстанции. И имейте с использованием процесса класс для управления потоками за этот процесс и получить свой статус завершения.

Слова предостережения по поводу примеров на эту тему. Вполне возможно, что примерами в тупике, если подпроцесс генерирует достаточно вывод переполнения системы. Более надежное решение требует осушения STDOUT STDERR процесса и в отдельных потоках.

Для получения дополнительной информации о ProcessBuilder см. в определении класса.

Copyright (C) 2004-2005 Sun Microsystems, Inc
Все права защищены.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>