David Morales
David Morales

Reputation: 33

How to format and save console output to file in Java?

Background: Hello! First of all, please have in mind that I'm fairly new to Java, thus, forgive me if I have something wrong. I have been trying to format my console and save its output to a text file for 2 days now. Here's my code so far:

I'm trying to set the format of the console to

[12/20/2017 23:55:30] program(message here)

and I'm doing it like this:

public class Format {
    private static final DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");

    PrintStream console = new PrintStream(System.out) {

        public void println(String x) {
            Date date = new Date();
            super.println("[" + sdf.format(date) + "] " + "program(" + x + ")");
        }
    };

Along with this:

    public void progStream() throws FileNotFoundException {
        System.setOut(console);
        System.out.println("This is a test.");
    }

Up to here it works just fine and I can see all the system outputs show up on the eclipse's console with the correct format. However, when I try to save it a text file it saves only the message. Without the format.

    public void progStream() throws FileNotFoundException {
        File log = new File("log" + System.currentTimeMillis() + ".txt");
        FileOutputStream fos = new FileOutputStream(log);
        PrintStream console = new PrintStream(fos);
        System.setOut(console);
        System.out.println("This is a test.");
    }

I have tried replacing System.out.println("message"); with console.print("message"); but I get the same issue. Unfortunately, I have run out of tutorials and forums to look out and I still can't find a solution to this. Thank you for your help.

Upvotes: 1

Views: 2868

Answers (2)

m. vokhm
m. vokhm

Reputation: 699

In your code, you never use the Format class you created to prepend your output with the date. You should have created an instance of this class and call the method println() of the console field of the newly created instance. Below is your code, slightly modified, that I suppose does what you want:

  import java.io.File;
  import java.io.FileNotFoundException;
  import java.io.FileOutputStream;
  import java.io.PrintStream;
  import java.text.DateFormat;
  import java.text.SimpleDateFormat;
  import java.util.Date;

  public class So_47900381 {

    static public class Format {
      private static final DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
      PrintStream console = new PrintStream(System.out) {;
        public void println(String x) {
          Date date = new Date();
          super.println("[" + sdf.format(date) + "] " + "program(" + x + ")");
        }
      };
    }

    public static void progStream() throws FileNotFoundException {
      File log = new File("log" + System.currentTimeMillis() + ".txt");
      PrintStream console = new PrintStream(new FileOutputStream(log));
      System.out.println("Writing to " + log.getPath());
      System.setOut(console);
      Format fmt = new Format();
      fmt.console.println("This is a test.");
    }

    public static void main(String[] args) {
      try {
       progStream();
      } catch (Exception x) { x.printStackTrace(); }
    }

  }

But I think there's no need to have a separate field, that is a descendant of the PrintStream and used to print to, inside the Format class. The class itself could descend from the PrintStream as well. Look at the code below:

  import java.io.File;
  import java.io.FileNotFoundException;
  import java.io.PrintStream;
  import java.text.DateFormat;
  import java.text.SimpleDateFormat;
  import java.util.Date;

  public class So_47900381_1{

    static public class Format extends PrintStream {
      private static final DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");

      public Format(File file) throws FileNotFoundException {
        super(file);
        System.setOut(this);
      }

      public void println(String x) {
        Date date = new Date();
        super.println("[" + sdf.format(date) + "] " + "program(" + x + ")");
      }
    }

    public static void progStream() throws FileNotFoundException {
      File log = new File("log" + System.currentTimeMillis() + ".txt");
      System.out.println("Writing to " + log.getPath());
      Format fmt = new Format(log);          // redirects the output to the file
      System.out.println("This is a test."); // now it's written to the file 
    }

    public static void main(String[] args) {
      try {
        progStream();
      } catch (Exception x) { x.printStackTrace(); }
    }

  }

And yes, look at the log4j and/or google for java logging.

Upvotes: 1

Bruno Medeiros
Bruno Medeiros

Reputation: 2389

I think that's what you want to achieve:

import java.lang.*;
import java.io.*;
import java.util.*;
import java.text.*;

public class HelloWorld {

  public static void main(String[] args) throws IOException {

    PrintStream console = new PrintStream(System.out);
    PrintStream file = new PrintStream(new FileOutputStream(new File("log" + System.currentTimeMillis() + ".txt")));  

    Format format = new Format();

    // console
    format.print("bla", console);

    // file
    format.print("bla", file);  
  }
}

public class Format {

  private static final DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");

  public void print(String x, PrintStream stream) {
     Date date = new Date();
     stream.println("[" + sdf.format(date) + "] " + "program(" + x + ")");
  }

}

PS.: If you really want to log things, I recommend you to consider a logging framework like log4j.

PS. 2: System.setOut(stream) does NOT seem a good idea as your standard output will be redirected to the file.

I hope my answer helps you :)

Upvotes: 0

Related Questions