2015-08-26 4 views
-1

Я работаю над программой Java, которая выполняет следующую команду: clamscan -r /. Однако эта команда занимает пару часов. Он также выпускает сотни строк вывода.

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

Я просмотрел другие подобные вопросы, но вывод не отображается до тех пор, пока команда не будет завершена.

Я использую Linux Mint 17.

Спасибо заранее!Java выполнить команду и получить вывод как ее запуск

+0

Покажите нам код, который вы используете, чтобы выполнить команду и получить выход ... – Codebender

+0

Посмотрите на код в вопросе: [Здесь] (http://stackoverflow.com/questions/21019172/getting- выход из-исполнительного-а-терминальной-команды-в-Java-кода выполняющейся-внутри-с). – pdf4664

+0

@ pdf4664 этот код сначала считывает выходной поток, затем поток ошибок. если ваша программа выводится в поток ошибок, она может блокироваться, пока программа не будет выполнена. вы можете либо попробовать мое решение, либо просто посмотреть, поможет ли вам сводка порядка (сначала прочитайте ошибку, затем stdout). – kritzikratzi

ответ

0

Предположим, у вас есть Process (предположительно, из Runtime.exec или ProcessBuilder.start) вы можете использовать этот маленький помощник, который я сделал.

Это немного запутанно, потому что я использую InputStreams для проверки доступности данных в сочетании с InputReaders для чтения символов. Это должно вести себя хорошо, даже с выходом unicode. Также не требуется второй поток для обработки тайм-аутов, поэтому, вероятно, это не так уж плохо.

import java.io.BufferedReader; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.util.function.Consumer; 

public class CmdTools{ 
    /** 
    * blocking read from process and copy to stdout 
    */ 
    public static void read(Process p, int timeout) throws IOException, InterruptedException{ 
     read(p, timeout, System.out::print, System.err::print); 
    } 

    /** 
    * blocking read from process 
    * @param timeout A timeout in milli seconds, or 0 for infinite 
    */ 
    public static void read(Process p, int timeout, Consumer<String> in, Consumer<String> err) throws IOException, InterruptedException{ 
     try(InputStream inStream = p.getInputStream(); 
     InputStream errStream = p.getErrorStream(); 
     Reader inReader = new InputStreamReader(inStream); 
     Reader errReader = new InputStreamReader(errStream)){ 
      long now = System.currentTimeMillis(); 
      long end = now + timeout; 
      int len; 
      char buffer[] = new char[4096]; 

      boolean canContinue = true; 
      while(canContinue){ 

       if(inStream.available() > 0){ 
        len = inReader.read(buffer, 0, Math.min(buffer.length, inStream.available())); 
        in.accept(new String(buffer,0,len)); 
       } 
       if(errStream.available() > 0){ 
        len = errReader.read(buffer, 0, Math.min(buffer.length, errStream.available())); 
        err.accept(new String(buffer,0,len)); 
       } 

       Thread.sleep(2); 

       boolean hasData = inStream.available() > 0 || errStream.available() > 0; 
       if(timeout == 0){ 
        canContinue = hasData || p.isAlive(); 
       } 
       else{ 
        canContinue = System.currentTimeMillis() < end && (p.isAlive() || hasData); 
       } 
      } 
     } 
    } 
} 
+0

Есть ли у вас версия совместимого с java 7? java.util.function не существует в java 7. – pdf4664

+0

@ pdf4664 очень легко переносить, но не забавно использовать. добавьте это к концу: 'public static interface Потребитель () {public void accept (T t); } '. Вместо 'read (p, timeout, System.out :: println, System.err :: print)' вы теперь пишите для java7: 'read (p, timeout, new Consumer () {public void accept (String s) {System.out.print (s);}}, новый пользователь () {public void accept (String s) {System.err.print (s);}}); '. В целом: переключитесь на java8, lambdas - отличное дополнение к языку. – kritzikratzi

 Смежные вопросы

  • Нет связанных вопросов^_^