используя Process.exec - PullRequest
       16

используя Process.exec

0 голосов
/ 12 августа 2010

Я хочу выполнить командный файл (это запустит другое Java-приложение) в середине моей программы.Я не хочу ждать или посмотреть, успешно ли он выполнен, и я не хотел регистрировать ошибки при выполнении этого командного файла.После того, как я запустил этот пакетный файл, я хочу заняться чем-то другим, а не ждать его после выполнения этого пакета.

Нужно ли мне позаботиться о stdout и stderr?Есть ли какой-нибудь способ избавиться от заботы о stdout и stderr.

Это мой второй пост, чтобы очистить мою путаницу в этой теме, поэтому, пожалуйста, будьте конкретны с вопросом и просто не кидайте ссылку на то, как обрабатывать.exe или processbuilder.

Любая помощь приветствуется.

Ответы [ 4 ]

3 голосов
/ 12 августа 2010

Краткий ответ: Нет. В соответствии с процессом ' javadocs ,

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

Поэтому вам нужно позаботиться об обработке stderr и stdout, если вы хотите, чтобы ваша программа была надежно удаленной.

Сказав это, если вы действительно не заботясь об их содержимом (что является плохой идеей - что, если пакет завершится неудачно с полезным сообщением об ошибке, которое вы отбрасываете?), вы можете просто запустить потоки, чтобы прочитать их, согласно Jay R. 'ответ s .Это позволит вашему логическому потоку продолжаться, не беспокоясь о состоянии потоков, и обработчики потоков будут работать в фоновом режиме, пока потоки не будут исчерпаны.Возможно, вы даже захотите создать оболочку вокруг Runtime.exec(), которая запускает потоки, чтобы сделать это для вас, если вы обнаружите, что делаете это много.

Я бы, однако, по крайней мере log вывод из пакетного процесса, если вы не собираетесь интерпретировать его в своем коде.Когда что-то пойдет не так с пакетом, анализ проблемы будет намного проще с выходом процесса на анализ.

2 голосов
/ 12 августа 2010

Я обнаружил, что если вы, по крайней мере, не съедаете stdout и stderr, в конце концов вам не хватит памяти. Это также мешало мне запускать более одного процесса одновременно.

Я использовал класс, который я назвал ProcessStreamEater, чтобы сделать это.

public class ProcessStreamEater implements Runnable
{
   private final Process proc;

   public ProcessStreamEater(Process proc)
   {
      this.proc = proc;
   }

   @Override
   public void run()
   {
      InputStreamReader r = new InputStreamReader(proc.getInputStream());
      try
      {
         while(r.read() != -1)
         {  // put stuff here if you want to do something with output
            // otherwise, empty
         }
      }
      catch(IOException e)
      {
         // handle IO exception
      }
      finally
      {
         if(r != null)
         {
            try
            {
               r.close();
            }
            catch(IOException c)
            {}
         }
      }
   }
}

Тогда, когда я использую это, чтобы поесть ...

   ProcessBuilder pb = new ProcessBuilder(args);
   pb.redirectErrorStream(true);
   final Process proc = pb.start();
   executorService.execute(new ProcessStreamEater(proc));

, где executorService был создан с помощью Executors.newCachedThreadPool ()

0 голосов
/ 12 августа 2010

Если ваш процесс не производит вывод в stdout или stderror, то вам, вероятно, не нужно обрабатывать это. Если ваш подпроцесс выдает выходные данные, он может блокироваться навсегда при попытке записи в стандартный вывод, это зависит от того, сколько буферов ОС загружает. Где-то здесь есть пример потокового очистителя, который все используют.

0 голосов
/ 12 августа 2010

Я думаю, что вам требуется только это:

Runtime run = Runtime.getRuntime();  
Process p = null;  
String cmd = "D:\\a.bat";     
try {     
  p = run.exec(cmd);
}catch(Exception e){
  //do handling
}

// ваш код

Не забудьте вызвать p.destroy () позже в вашем коде.Вы также можете создавать код выше в отдельном потоке.Надеюсь, это поможет.

...