Процесс, выполняемый в цикле, не регистрируется каждый раз

#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 каждый раз, когда выполняли печать?