#java #linux #process #stream #rsync
#java #linux #процесс #поток #rsync
Вопрос:
У меня есть класс, в котором я могу запускать команды rsync из сценария оболочки.
Все работает так, как должно, за исключением случаев записи выходных данных процесса (instream и потока ошибок) в файл.
У меня есть цикл в моем классе, который допускает 5 запусков в случае сбоя процесса, и при каждом запуске каждый поток / запись / считыватель инициализируется и полностью закрывается.
Проблема в том, что файл записывается только один или два раза за 5 запусков, и выводятся никогда одни и те же запуски. Я установил 10-секундный режим ожидания после процесса, чтобы сделать вывод более читаемым, и я мог видеть, что единственный вывод, записываемый в файл, был через 20 и 30 секунд или через 10 и 40 секунд и т.д.
Каждый вывод процесса записывается на консоль, но не в файл.
Мой код выглядит следующим образом. Любые советы будут оценены.
private static void run() throws IOException {
while (retry amp;amp; NUMBER_OF_TRIES >= tries){
InputStream in = null;
PrintStream out = null;
InputStream errIn = null;
try {
// get runtime object to run cmd
Runtime RT = Runtime.getRuntime();
Process PR = RT.exec( cmd );
errIn = PR.getErrorStream();
in = PR.getInputStream();
out = new PrintStream(new FileOutputStream(new File(output), true));
System.out.println("file output initialised");
StreamGobbler inConsumer = new StreamGobbler( in, new Date() " OUTPUT: ", out );
StreamGobbler errConsumer = new StreamGobbler( errIn, new Date() " ERROR: ", out );
System.out.println("Starting consumer threads");
inConsumer.start();
errConsumer.start();
Thread.sleep(10000);
int exitVal = PR.waitFor();
if (exitVal > 0){
retry = true;
tries ;
} else {
retry = false;
}
System.out.println("ExitValue: " exitVal);
// Wait for the consumer threads to complete
inConsumer.join();
errConsumer.join();
} catch ( Exception e ) {
e.printStackTrace();
System.out.println( "failed: " e.getMessage() );
} finally {
// the StreamConsumer classes will close the other streams
if ( out != null ){
out.close();
}
if (in != null){
in.close();
}
if (errIn != null){
errIn.close();
}
}
}
}
Ответ №1:
я никогда не видел, чтобы ваш объект printstream «out» когда-либо использовался, кроме его инициализации. Если вы хотите выполнить запись в файл, вы должны вызвать объект printstream.
System.out.println("ExitValue: " exitVal);
//now call the printstream object
out.print("ExitValue: " exitVal);
//flushing will force the string to be written to the file
out.flush();
Вы можете следовать приведенному выше коду каждый раз, когда вы пишете в консоль, и вы хотите записать в файл, с помощью которого вы создали свой объект printstream.
Комментарии:
1. Он используется в классе StreamGobbler . Я должен был упомянуть. Но я упоминал, что он записывается в файл несколько раз из 5, просто не все 5
2. вы уверены, что каждый процесс успешно запускается и останавливается?
3. ДА. Это процесс rsync, и он каждый раз копирует файлы. Он выводит поток на консоль, а не в файл
4. вы очищали () объект printstream каждый раз, когда выполняли печать?