0

When my program starts, it opens a file and writes to it periodically. (It's not a log file; it's one of the outputs of the program.) I need to have the file available for the length of the program, but I don't need to do anything in particular to end the file; just close it.

I gather that for file I/O in Java I'm supposed to implement AutoCloseable and wrap it in a try-with-resources block. However, because this file is long-lived, and it's one of a few outputs of the program, I'm finding it hard to organize things such that all the files I open are wrapped in try-with-resources blocks. Furthermore, the top-level classes (where my main() function lies) don't know about this file.

Here's my code; note the lack of writer.close():

public class WorkRecorder {

    public WorkRecorder(String recorderFile) throws FileNotFoundException {
        writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(recorderFile)));
    }

    private Writer writer;

    public void record(Data data) throws Exception {

        // format Data object to match expected file format
        // ...

        writer.write(event.toString());
        writer.write(System.lineSeparator());
        writer.flush();
    }
}

tl;dr do I need to implement AutoCloseable and call writer.close() if the resource is an opened output file, and I never need to close it until the program is done? Can I assume the JVM and the OS (Linux) will clean things up for me automatically?

Bonus (?): I struggled with this in C#'s IDisposeable too. The using block, like Java's try-with-resources construct, is a nice feature when I have something that I'm going to open, do something with quickly, and close right away. But often that's not the case, particularly with files, when the access to that resource hangs around for a while, or when needing to manage multiple such resources. If the answer to my question is "always use try-with-resources blocks" I'm stuck again.

Logical Fallacy
  • 3,017
  • 5
  • 25
  • 41

3 Answers3

0

I have similar code that doesn't lend itself to being wrapped in a try-with-resources statement. I think that is fine, as long as you close it when the program is done.

Just make sure you account for any Exceptions that may happen. For example, in my program, there is a cleanup() method that gets called when the program is shut down. This calls writer.close(). This is also called if there is any abnormal behavior that would cause the program to shut down.

If this is just a simple program, and you're expecting the Writer to be open for its duration, I don't think it's really a big deal for it to not be closed when the program terminates...but it is good practice to make sure your resources are closed, so I would go ahead and add that to wherever your program may shut down.

Evan LaHurd
  • 977
  • 2
  • 14
  • 27
0

You should always close resources or set them to null so it can be picked up by the garbage collector in Java. Using try-with-resource blocks is a great way to have Java automatically close resources when you're done with them. Even if you use it for the duration of the program, it is good programming practice to close it even at the end. Some might say you don't need to, I personally would say just go ahead and do it and here's why:

"When a stream is no longer needed, always close it using the close() method or automatically close it using a try-with-resource statement. Not closing streams may cause data corruption in the output file, or other programming errors."

-Introduction to Java Programming 10th Edition, Y. Daniel Liang

If possible, just run the .close() method on the resource at the very end of the program.

Brooke
  • 3
  • 4
  • Data corruption would be bad. Is that possible in this case? It's just a text file. I'd be surprised if failing to call `writer.close()` would cause the text file to become corrupted. – Logical Fallacy Feb 26 '16 at 21:19
  • I'm not certain on what causes the corruption if you do not close the file. You'd have to do more research on what causes the corruption (there is probably an exception, like I said more research). For a simple text file, the probability is probably very low if any at all so you're probably safe to go with not closing it, but it is a good programming practice to close it. – Brooke Feb 26 '16 at 21:42
0

I (now) think a better answer is "It depends" :-). A detailed treatment is provided by Lukas Eder here. Also check out the Lambda EG group post.

But in general, it's a good idea to return the resource back to the operating system when you are done with it and use try-with-resources all the time (except when you know what you are doing).

Community
  • 1
  • 1
Kedar Mhaswade
  • 4,535
  • 2
  • 25
  • 34