-2

I have a Java program littered with values I want to log to a txt file. I'm new to the language and finding it not so straight forward.

I created a Logger class:

public static void loggerMain(String content) {    
    try {
        PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("debug.txt", true)));
        out.println(content);
        out.close();
    } catch (IOException e) {
        //exception handling left as an exercise for the reader
    }
}

I then call the method in another class:

Logger.loggerMain("testing");

It logs the String but if I then run the script again, it will append the same String to a new line.But I don't want the same println to be appended each time the script is called. I want to override the file. How would I go about this?

If I change the FileWriter argument to False, the file will only log the latest call to the method. e.g.:

Logger.loggerMain("testing1");
Logger.loggerMain("testing2");

Only Logger.loggerMain("testing2"); will be logged. I know why, it's because I'm creating a new file each time I call the method.. but I really don't know the solution to this!

arsenal88
  • 1,040
  • 2
  • 15
  • 32
  • Your question is unclear. What do you mean by "I don't want the same `println` to be appended each time the script is called. *I want to override the file.*"? Based on last sentence it looks like you want to get rid of old content of file and replace it with new content. But in that case changing `true` to `false` is what you would want, but later you said you tried that and it still doesn't do what you want. Can you explain what you expect to happen when you call `Logger.loggerMain("foo"); Logger.loggerMain("Bar")`? How resulting file should look like? – Pshemo Jun 25 '18 at 12:24
  • The resulting file will just contain 'Bar', as this was the last call to LoggerMain – arsenal88 Jun 25 '18 at 12:25
  • I am not asking what it *will* contain, I am asking what you *want/expect* it to contain. Should it contain only "Bar"? If yes, then what is the problem with changing `true` to `false` (which should achieve exactly that)? – Pshemo Jun 25 '18 at 12:27
  • I want it to contain 'foo', 'bar'. – arsenal88 Jun 25 '18 at 12:28
  • @arsenal88 have a look at my question. I assume this might solve your problem. if not then please clarify your question further – Lino Jun 25 '18 at 12:29
  • Can you be more precise about expected content? Should I take it literally and assume you want to add quotes and commas like `'foo','bar'`? Or maybe should it be one line without quote or commas like `'foobar'` or maybe just commas `foo,bar`? – Pshemo Jun 25 '18 at 12:31

2 Answers2

2

If I understood you correctly you want to clear the log for every time the programm is executed. You can do this with the following addition to the Logger class:

class Logger {
    private static boolean FIRST_CALL = true;

    public static void loggerMain(String content) {    
        try {
            PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("debug.txt", !FIRST_CALL)));

            if(FIRST_CALL){
                FIRST_CALL = false;
            }
            out.println(content);
            out.close();
        } catch (IOException e) {
            //exception handling left as an exercise for the reader
        }
    }
}

With the variable FIRST_CALL we track if the logger has been executed for the first time in the current script context. If it is, we overwrite the file, by passing in false (!FIRST_CALL) into the FileWriter

Lino
  • 19,604
  • 6
  • 47
  • 65
  • I tried this implementation and when calling the method twice, it still only takes the latest method's print statement. I want both method calls to be in the txt output. Thanks – arsenal88 Jun 25 '18 at 12:31
1

Just a re-iteration of the other answer:

class Logger {
    private static boolean FIRST_CALL = true;

    public static void loggerMain(String content) {    
        try (
            PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("debug.txt", !FIRST_CALL)))) {
            FIRST_CALL = false;
            out.println(content);
        } catch (IOException e) {
            //exception handling left as an exercise for the reader
        }
    }
}
  1. try-with-resources will spare you an explicit close() call, and will properly close the resource regardless of completing the block normally or with an exception.
  2. This one is subjective: as the code will touch FIRST_CALL anyway, I feel it simpler to set it without the extra check.
tevemadar
  • 12,389
  • 3
  • 21
  • 49
  • Thought about those points too. The last one bothers me a bit. As I don't like overwriting a variable always. But I am not sure what is more time consuming, checking it or overwriting it. Anyway, good answer! :) – Lino Jun 25 '18 at 12:50
  • @Lino Yes, on the CPU level you are absolutely right (https://stackoverflow.com/questions/47417481/what-specifically-marks-an-x86-cache-line-as-dirty-any-write-or-is-an-explici), just here files are involved, so a dirty cache-line matters very little. – tevemadar Jun 25 '18 at 13:59