Groovy / Java управление процессом перехват / прослушивание вывода - PullRequest
2 голосов
/ 10 августа 2009

В Groovy есть хороший механизм выполнения процессов, и я бы хотел его использовать.
Есть метод consumeProcessOutput, который выполняет всю необходимую работу. Но я хочу, чтобы мои дополнительные функции вводились каждый раз, когда consumeProcessOutput вызывает append или что-то в out экземпляре.

public class ProcessExecutor {
   static public void execute(IOutput output, String processName) {
      def process = processName.execute()

      def out = new StringBuffer()
      process.consumeProcessOutput(out, out)

      process.waitFor()
   }
}

Мне известно о

use (MyStringBufferIntercept) {
   process.consumeProcessOutput(out, out)
}

Но они, кажется, работают только для текущего потока, а consumeProcessOutput создает дополнительные потоки.

Так есть ли решение для прослушивания строк, добавляющих и вызова output.addLine(line) и output.addErrorLine(line)?

Пока у меня есть только одно решение, которое не работает, когда вывод ошибок идет вместе с нормальным выводом довольно быстро: порядок меняется.

  def process = processName.execute()

  def inThread = Thread.start {
     process.in.eachLine{ line -> output.addLine(line)}
  }

  def errThread = Thread.start {
     process.err.eachLine{ line -> output.addErrorLine(line)}
  }

  inThread.join()
  errThread.join()

  process.waitFor()

Я согласен с решением Java. Но я склонен думать, что Groovy должен быть более элегантным.

1 Ответ

1 голос
/ 17 августа 2009

Мне не нравится соглашение, используемое Groovy для чтения из process.in и process.err и записи в process.out. Javadocs должен быть более четким в этом. Казалось бы, err и out будут двумя в своем роде, а in нечетным.

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

class P {
 static public void execute( String processName) {
  def process = processName.execute()
  def output = new StringBuffer()

  def outline = { line -> output += line + '\n' }

 def inThread = Thread.start {
         process.in.eachLine{ outline it }
   }

 def errThread = Thread.start {
          process.err.eachLine{ outline it }
   }

       inThread.join()
       errThread.join()
       process.waitFor()
       println output
    }
 }

 def p = new P();
 p.execute("ls -l");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...