2012-06-05 2 views
1

В настоящее время возникают проблемы с перенаправлением вывода небольшой оконной консоли на файл журнала. Моему Java-приложению необходимо запустить вызов Runtime.exec(), не дожидаясь его завершения и записи журнала. Вот мой класс регистратор:Перенаправить вывод системного вызова в файл с помощью Java

public class BatchThreadLogger extends Thread { 
    private Process process; 
    private String logFilePath; 
    private static final Logger logger = Logger.getLogger(BatchThreadLogger.class); 

    public BatchThreadLogger(Process process, String logFilePath) { 
    this.process = process; 
    this.logFilePath = logFilePath; 
    } 

    public void run() { 
    try { 
     // create logging file 
     File file = new File(logFilePath); 
     file.createNewFile(); 

     // create a writer object 
     OutputStream os = new FileOutputStream(file); 
     PrintWriter pw = new PrintWriter(os); 

     // catch the process output in an InputStream 
     InputStreamReader isr = new InputStreamReader(process.getInputStream()); 
     BufferedReader br = new BufferedReader(isr); 

     // wait for the process to complete 
     int processStatus = process.waitFor(); 

     // redirect the output to the log file 
     String line = null; 
     while ((line = br.readLine()) != null) { 
     pw.println(line); 
     } 

     // add a small message with the return code to the log 
     pw.println("********************************************"); 
     pw.println("********************************************"); 
     pw.println("Batch call completed with return status " + processStatus); 

     pw.flush(); 
     os.close(); 
    } 
    catch (IOException e) { 
     logger.error("IOException raised during batch logging on file " + logFilePath, e); 
    } 
    catch (InterruptedException e) { 
     logger.error("InterruptedException raised during batch process execution", e); 
    } 
    } 
} 

Мой вызов довольно прост:

Process process = Runtime.getRuntime().exec(command); 
BatchThreadLogger logger = new BatchThreadLogger(process, logFilePath); 
logger.start(); 

Моя команда в настоящее время просто звоню мой файл Test.bat с двумя параметрами. Моя пробная партия теперь просто сделать:

echo "BATCH CALLED WITH PARAMETER %1 AND %2" 
exit 

Мой лог-файл, однако делает только содержит:

******************************************** 
******************************************** 
Batch call completed with return status 0 

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

Любая помощь будет принята с благодарностью, я что-то не хватает, но не могу понять, что ...

ответ

1

Вы не считывая стандартную ошибку процесса, который вы создаете.

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

Я бы рекомендовал заменить ваше использование Runtime.getRuntime().exec(...) с ProcessBuilder, используя что-то вроде следующего:

ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", "test.bat", "One", "Two"); 
pb.redirectErrorStream(true); 
Process process = pb.start(); 

Линия pb.redirectErrorStream(true); перенаправляет процесс стандартную ошибку в стандартный выходной поток, так что вы не имеете для чтения из двух потоков (стандартный вывод и стандартная ошибка) в двух отдельных потоках.

+0

Я не уверен в вашем ответе. Интересно, как эхо-текст в пакетном файле может рассматриваться как ошибка и, таким образом, направлен на поток ошибок процесса выполнения. Чтобы быть уверенным, я заменил вызов getInputStream() 'getErrorStream()' и он все еще не работает ... ничего в файле журнала ... – Wis

+0

Я также добавил случайный 'ping www.google. ch' после эхо-сигнала, просто чтобы убедиться, что выход эха не перенаправляется на специальный поток или любой трюк, подобный этому ... в журналах все еще ничего. BTW, код, который я опубликовал, работает в Linux. Что касается вашего предложения ProcessBuilder, я увижу, может ли он заменить вызов Runtime.exec() easyilly. – Wis

+0

Я предполагаю, что вы можете получить ошибку при попытке запустить пакетный файл, который не существует или не может быть прочитан из-за проблем с разрешениями. Тем не менее, странно, что выхода нет. Не могли бы вы поделиться тем, что находится в вашей переменной 'command'? Также является ли это приложение (например, командной строки, веб-приложение, графический интерфейс, сервис)? –

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

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