перенаправление вывода из консоли в текстовый файл - PullRequest
0 голосов
/ 11 июня 2019

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

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

Часть упражнения заключается в выводе информации как на консоль, так и в текстовый файл.

Мой код выглядит следующим образом:

class ProcessDemo 
{
static int done = 0;

//main method to instantiate both thread processes 
public static void main(String[]args) throws InterruptedException 
{   
    final ProducerConsumer PC = new ProducerConsumer();

    //instantiation of a new thread object, inside of which the run method is overridden 
    Thread producer = new Thread(new Runnable()
    {
        @Override
        public void run() 
        {       
            try {
                PC.produce();
            }   
            catch(InterruptedException e){
                e.printStackTrace();
            }   
        }
    });

    //instantiate second thread object, inside of which the run method is overridden  
    Thread consumer = new Thread(new Runnable()
    {
        @Override
        public void run()
        {
            try {   
                PC.consume();       
            } 
            catch(InterruptedException e){
                e.printStackTrace();
            }
        }   
    });

    //calling the start method to initiate both the producer and consumer threads
    producer.start();
    consumer.start();
} 

public static class ProducerConsumer
{
    int[] buffer = new int[5];
    int capacity = 5;
    int counter = 0;
    int producerIndex = 0;
    int consumerIndex = 0;
    static int done = 0;



    public void consume() throws InterruptedException
    {
        PrintWriter output = null;
        try
        {
            //instantiating print writer object to output results to a designated file 
            output = new PrintWriter("results.txt");
        }
        catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }

        while (true)
        {   
            long sleepTimeout = (long)(((Math.random()*2000.00)+2000.00));
            Thread.sleep((long)(sleepTimeout));

            System.out.println("consumer random sleep for " + sleepTimeout/1000.00 + " seconds");
            output.println("consumer random sleep for " + sleepTimeout/1000.00 + " seconds");

            while (producerIndex == consumerIndex && done != 1)
            {   
                System.out.println("\n*****BUFFER EMPTY, consumer sleeping for 1 sec\n");
                output.println("\n*****BUFFER EMPTY, consumer sleeping for 1 sec\n");
                Thread.sleep(1000);
            }

            int valueRead = buffer[consumerIndex];
            System.out.println("\nConsumer consumed item : " + valueRead + " from index: " + consumerIndex);
            output.println("\nConsumer consumed item : " + valueRead + " from index: " + consumerIndex);

            consumerIndex = (consumerIndex + 1)%capacity;
            counter--;
            System.out.println("counter is now: " + counter);
            output.println("number of full slots in buffer: " + counter);

            if (counter == 0 && done == 1)
            {   
                System.out.println("-------------All Done---------------");
                output.println("-------------All Done---------------");
                break;
            }               
        }
    }
}

}

, когда я переопределяю методы run () в двух созданных мной объектах потока, а затем помещаю операторы печати внутриметод run, я смог вывести на консоль и в указанный файл, используя следующий код:

PrintWriter output = null;
    try
    { 
        output = new PrintWriter("results.txt");
    }
    catch (FileNotFoundException e1) {
        e1.printStackTrace();
    }

    System.out.println("print something to console");
    output.println("print something to output file");

однако при перемещении операторов print и объекта writeer из объектов потока вМетоды «производить» и «потреблять», которые я определил в отдельном классе (публичный статический класс ProducerConsumer), тогда, хотя вывод на консоль в порядке, файл вывода пуст.

В таких ситуациях я прибегал к использованию следующей техники:

outputFile = new File(outputFileName);
output_obj = new PrintStream(outputFile);

console = System.out;
System.setOut(output_obj);
System.out.println("print something to output file");

System.setOut(console);
System.out.println("print something to console");

Является ли это наилучшим способом вывода на консоль и в текстовый файл?Этот метод кажется, что он может быть не самым эффективным.Другое дело, что я должен продублировать операторы print, что добавляет большую часть моего кода, если есть лучший способ реализовать эту функциональность, мне было бы очень интересно узнать его.

...