2

Is there a way to save the whole console output to a file when multithreading? I'm working with 5 threads. I had this idea that i can put a printstream in the run-method.

example:

public void run()  {
 try{
    PrintStream out = new PrintStream(file);
    stopExecute stop = new stopExecute();
    Thread t = new Thread(stop);
    Scanner in = new Scanner(System.in);
    t.start();

        while (!in.hasNextLine()) 
    {
        classThatUsingMultipleThrads();
        System.out.println("Finished");
        anotherClassThatUsingThreads(); 
        System.out.println("Finished"); 
    }
        System.out.prinln("User stopped the execution");
        stop.keepRunning = false;
        System.setOut(out);

       }
    catch(IOException e){System.out.println(e);}

Problem here is that it's only saving the output "User stoped the execution" and everything in the whileloop are not saved. Or the outputstream from other classes.

I've tried to put the

System.setOut(out);

in the while-loop, but didn't help.

Edit: Spell correction

Micropop
  • 21
  • 5

3 Answers3

0
  try {
  System.setOut(new PrintStream(new File("output-file.txt")));
 } 
 catch (Exception e) {
  e.printStackTrace();
 }

thanks to: System.out to a file in java

Community
  • 1
  • 1
0

You should probably look into using a logging library such as Log4J. However you could also use something like a TeeOutputStream. This type of output stream writes to 2 other streams when called. A few libraries have great implementations but you can also write one yourself. I whipped this one up real quick.

You could set the output stream for your entire program in your main method to use this TeePrintStream, then all calls to System.out.* will write data to the usual System.out and your FileOutputStream.

Theres also an implementation of the TeePrintStream here http://www.java2s.com/Code/Java/File-Input-Output/TeePrintStreamteesallPrintStreamoperationsintoafileratherliketheUNIXtee1command.htm

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;

public class SO34042494 {
    public static void main(String[] args) throws FileNotFoundException {
        System.setOut(new TeePrintStream(System.out, new FileOutputStream(new File("x:\\output.txt"))));

        System.out.println("Check check");
        System.out.println("1");
        System.out.println(2);
        System.out.println(3L);
    }

    public static class TeePrintStream extends PrintStream {
        private final OutputStream tee;

        public TeePrintStream(PrintStream original, OutputStream tee) {
            super(original);
            this.tee = tee;
        }

        @Override
        public void write(byte[] b) throws IOException {
            super.write(b);
            tee.write(b);
        }

        @Override
        public void write(byte[] buf, int off, int len) {
            super.write(buf, off, len);
            try {
                tee.write(buf, off, len);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        @Override
        public void write(int b) {
            super.write(b);
            try {
                tee.write(b);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        @Override
        public synchronized void close() {
            try {
                tee.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                super.close();
            }
        }
    }
}

The TeePrintStream I have here is something I just threw together, please if your going to use this in a production project polish it up and test it thoroughly

ug_
  • 11,267
  • 2
  • 35
  • 52
0

Okej i think i solved it. In my main i just did like this:

public static void main(String[] args) {
Prinstream out = new Prinststream(file);

/*   
   Do some things like start threads, call objects etc..
   .
   .
   .
   .
*/
  System.setOut(out);

I think that when all threads are started and doing their things(i do assign a object to each thread) the printstream will catch every console-output that occurs in other classes. This didn't work before i edited my stopExecute class.

public class stopExecute implements Runnable {
  Scanner scan = new Scanner(System.in);    
  private Object[] obj;

public stopExecute(Object[] obj)
{
    this.obj = obj;
}

public void run() {
    while(true){
        stop();
    }
}
public void stop() {
    if(scan.hasNextLine()){
        System.out.println("Stopped");
        System.exit(0); 
    }
  }
}

Thank you for your help guys. I will look into your suggestions and try them. In this solution i'm unable to use Log4J. But i will definitely check it out.

Micropop
  • 21
  • 5