It turns out that almost nobody closes resources in Java correctly. Programmers either do not use try-finally
block at all, or just put resource.close()
If your only problem with IOUtils.closeQuietly
is that it ignores exceptions on OutputStreams, then you can either simply call close()
on them, or create your own utility class which automatically treats the two differently, like this:
public static void close(Closeable resource)
{
try
{
resource.close();
}
catch(Exception e)
{
//swallow exception
}
}
public static void close(OutputStream o)
{
//throw any exceptions
o.close();
}
The correct overloaded method will be selected at compile time in all common situations, although if you're passing OutputStream
s around as Closeable
s then you'll have to change this to do a dynamic instanceof
check to make sure OutputStream
s always throw exceptions.
Though anonymous class is quite verbose, it's still acceptable in java land
new TryWithResource<InputStream>(){
protected InputStream init() throws Exception {
return new FileInputStream("abc.txt");
}
protected void use(InputStream input) throws Exception{
input.read();
}
};
----
abstract class TryWithResource<R>
{
abstract protected R init() throws Exception;
abstract protected void use(R resource) throws Exception;
// caution: invoking virtual methods in constructor!
TryWithResource() throws Exception
{
// ... code before
R r = init();
use(r);
// ... code after
}
}
I've found a good replacement for try-with-resources
. It uses Lombok library with annotation processing:
@Cleanup InputStream in = new FileInputStream(args[0]);
@Cleanup OutputStream out = new FileOutputStream(args[1]);
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
However, it doesn't handle exception correctly. This bug is more than 1 year old and still is not closed: https://code.google.com/p/projectlombok/issues/detail?id=384