Reputation: 1807
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:
Part
object in a Servlet
. There is a part.getInputStream()
which returns an InputStream
.byte[]
, which is passed on by some Web Services. The InputStream
can be obtained with a new ByteArrayInputStream
.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
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