user1156544
user1156544

Reputation: 1807

Closing InputStream contained in an object

What is the proper way to close an InputStream that is part of an object?

class Uploadable {
    InputStream is;
    ...
}

This object is passed on to an upload method:

uploadMethod(Uploadable up);

The way to create the Uploadable is either:

The problem is once the InputStream is in the object, the ability to close it nicely is sort of lost, because the object is created in one place but used in other places. This limits my ability to use try-with-resources, because the object might not be used inside the context of the try block. The only way I see is to make is immutable and create a specific Uploadable.close() method that closes the InputStream whenever the use is done. Alternatively, I can store a byte[] instead of InputStream and convert the part.getInputStream() into an array of bytes. However, it seems a bad performance decision to me, since I will get an InputStream, convert it to byte[] to be latter converted again to InputStream in the upload method.

I suppose this is a very well known problem but I can't find best practices. Oracle always closes the object in the try-with-resources block or the finally block.

Upvotes: 0

Views: 48

Answers (1)

daniu
daniu

Reputation: 14999

I'd suggest you implement AutoCloseable yourself in the Uploadable and leave closing that to the creator/caller.

class Uploadable implements AutoCloseable {
    InputStream is;
    public void close() throws IOException {
        if (is != null) {
            is.close();
        }
    }
}

This way, the Uploadable can be created in a try-with-resource block if needed, or not - in which case the responsibility of closing it is left to the client code.

Upvotes: 2

Related Questions