Главная » Java » Класс Process

0

 

   Каждый из методов Runtime .exec возвращает объект Process, отвечающий вновь созданному дочернему процессу. Объект предоставляет методы управления процессом, относящиеся к двум категориям. Во-первых, объект Process позволяет получать ссылки на соответствующие дочернему процессу объекты потоков ввода (input), вывода (output) данных и сообщений об ошибках (error).

 

 public abstract OutputStream getOutputStream()

Возвращает объект OutputStream, присоединенный к стандартному потоку ввода  процесса. Данные, выводимые в поток, который представляется возвращенным объектом OutputStream, воспринимаются потоком ввода процесса.

 public abstract inputstream getlnputStream()

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

public abstract Inputstream getErrorStream()

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

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

 

public static Process userProg(string cmd)

      throws lOException

{

Process proc = Runtime.getRuntime().exec(cmd);

plugTogether(System.in,     proc.getOutputStream ()) ;

 plugTogether(System.out,   proc.getlnputStream());

plugTogether(System.err,   proc.getErrorStreamO) ;

return proc;

}

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

   Методы объекта Process, относящиеся к другой категории, позволяют управлять состоянием процесса.

public abstract int waitFor()  throws interruptedException

Приостанавливает выполнение потока вычислений, инициировавшего текущий процесс, до момента завершения последнего, после чего возвращает значение кода завершения (exit value), подобное тому, которое передается методу System.exit или его аналогам (нуль означает нормальное завершение, а ненулевая величина — какое-либо нарушение). Если к моменту вызова метода выполнение процесса уже закончено, метод просто возвращает значение.

public abstract int exitvalueO

Возвращает код завершения процесса. Если процесс еще не завершен, выбрасывается исключение типа illegal ThreadStateException.

public abstract void destroy()

Уничтожает текущий процесс. Если процесс уже завершен, метод никаких действий не выполняет. (Утилизация объекта Process сборщиком мусора, если таковая происходит, не означает, что процесс, соответствующий объекту, уничтожается — просто он перестает быть доступным для внешних запросов и воздействий.)

 

 

Рассмотрим пример метода, возвращающего массив значений String с итогами выполнения команды Is, которой передаются соответствующие аргументы командной строки. Метод выбрасывает исключение типа LSFailedException, если команда завершает выполнение неуспешно:

public string[]   ls(String dir,   String opts)

throws  LSFailedException

{

try {

// Формирование и выполнение команды

 String[] cmdArray = { "/bin/Is", opts, dir };

 Process child = Runtime.getRuntime().exec(cmdArray);

InputStream lsOut = child.getlnputStream();

 InputStreamReader r = new inputStreamReader(lsOut);

 BufferedReader in = new BufferedReader(r);

 

// Считывание итогов работы команды

List lines = new ArrayList();

String line;

while  ((line = in. readLineO)   != null)

     lines.add(line);

if (child.waitForO   != 0)  // Результат неуспешен

throw new LSFailedException(child.exitvalue());

   return  (String[])lines.toArray(new String[]   {  });

 } catch  (LSFailedException  e)   {

   throw e;

} catch  (Exception e)   {

   throw new LSFailedException(e.toString());

   }

}

Поскольку желательно получить итоговый набор данных, возвращаемых командой Is, в виде массива строк, объект потока ввода isOut передается в качестве параметра объекту-преобразователю типа InputStreamReader. Если же требуется трактовать результаты работы команды, выполняемой в контексте дочернего процесса, как поток байтов, задача упрощается. При необходимости использования второй формы метода exec начальные строки кода блока try следует записать так:

 

String cmd = "/bin/Is  " + opts + "  " + dir;

Process child = Runtime.getRuntime().exec(cmd);

 

   Уместно напомнить еще раз, что Process — это абстрактный класс. В каждой конкретной реализации виртуальной машины Java могут быть предусмотрены один или несколько соответствующих классов, производных от Process, которые способны взаимодействовать с реальными процессами, выполняющимися под управлением операционной системы, и содержать те или иные функциональные средства программирования, отвечающие природе этой системы. За дополнительной информацией о подобных расширенных средствах обращайтесь к документации из комплекта поставки виртуальной машины.

   Наконец, следует заметить, что жестких требований, касающихся того, каким образом должен выполняться дочерний процесс по отношению к  родительскому — синхронно или асинхронно, — не существует:  в конкретной системе

 

метод exec вполне способен, например, блокировать родительский процесс до момента завершения дочернего.

 

Источник: Арнолд, Кен, Гослинг, Джеймс, Холмс, Дэвид. Язык программирования Java. 3-е изд .. : Пер. с англ. – М. : Издательский дом «Вильяме», 2001. – 624 с. : ил. – Парал. тит. англ.

По теме:

  • Комментарии