La siguiente solución arroja una excepción correctamente si el cierre falla sin ocultar una posible excepción antes del cierre.
try {
InputStream in = new FileInputStream(file);
try {
// work
in.close();
} finally {
Closeables.closeQuietly(in);
}
} catch(IOException exc) {
// kernel panic
}
Esto funciona porque se llama por segunda vez has no effect.
Esto se basa en guayaba Closeables, pero se puede escribir su propio método closeQuietly si se prefiere, como se muestra en squiddle (consulte también serg10).
Informar de un error de cierre, en el caso general, es importante porque close podría escribir algunos bytes finales en la secuencia, p. debido al almacenamiento en búfer. Por lo tanto, su usuario quiere saber si falló, o usted probablemente quiera actuar de alguna manera. Por supuesto, esto podría no ser cierto en el caso específico de un FileInputStream, no lo sé (pero por las razones ya mencionadas, creo que es mejor informar un error de cierre si se produce de todos modos).
El código anterior es un poco difícil de comprender debido a la estructura de los bloques try integrados. Podría considerarse más claro con dos métodos, uno que arroje una IOException y otro que lo atrape. Al menos eso es lo que yo optaría.
private void work() throws IOException {
InputStream in = new FileInputStream(file);
try {
// work
in.close();
} finally {
Closeables.closeQuietly(in);
}
}
public void workAndDealWithException() {
try {
work();
} catch(IOException exc) {
// kernel panic
}
}
Basado en http://illegalargumentexception.blogspot.com/2008/10/java-how-not-to-make-mess-of-stream.html (referenciado por McDowell).
'fis' no puede ser nulo en el punto en que lo está probando. Puede ser nulo en el bloque 'finally' que falta donde debería probarlo y cerrarlo. Pero la pregunta es obsoleta desde la introducción de la sintaxis 'try-with-resources'. – EJP
He modificado el código en consecuencia solo para que las personas no sean engañosas. –