@@ -41,45 +41,73 @@ private IOUtils() {
41
41
}
42
42
43
43
/**
44
- * Closes all given <tt>Closeable</tt>s. Some of the <tt>Closeable</tt>s may be null; they are ignored. After everything is closed, the
45
- * method either throws the first exception it hit while closing, or completes normally if there were no exceptions.
44
+ * Closes all given <tt>Closeable</tt>s. Some of the <tt>Closeable</tt>s may be null; they are
45
+ * ignored. After everything is closed, the method either throws the first exception it hit
46
+ * while closing with other exceptions added as suppressed, or completes normally if there were
47
+ * no exceptions.
46
48
*
47
49
* @param objects objects to close
48
50
*/
49
51
public static void close (final Closeable ... objects ) throws IOException {
50
- close (Arrays .asList (objects ));
52
+ close (null , Arrays .asList (objects ));
51
53
}
52
54
53
55
/**
54
- * Closes all given {@link Closeable}s.
56
+ * Closes all given <tt>Closeable</tt>s. Some of the <tt>Closeable</tt>s may be null; they are
57
+ * ignored. After everything is closed, the method adds any exceptions as suppressed to the
58
+ * original exception, or throws the first exception it hit if {@code Exception} is null. If
59
+ * no exceptions are encountered and the passed in exception is null, it completes normally.
55
60
*
56
61
* @param objects objects to close
62
+ */
63
+ public static void close (final Exception e , final Closeable ... objects ) throws IOException {
64
+ close (e , Arrays .asList (objects ));
65
+ }
66
+
67
+ /**
68
+ * Closes all given <tt>Closeable</tt>s. Some of the <tt>Closeable</tt>s may be null; they are
69
+ * ignored. After everything is closed, the method either throws the first exception it hit
70
+ * while closing with other exceptions added as suppressed, or completes normally if there were
71
+ * no exceptions.
57
72
*
58
- * @see # close(Closeable...)
73
+ * @param objects objects to close
59
74
*/
60
75
public static void close (final Iterable <? extends Closeable > objects ) throws IOException {
61
- Exception ex = null ;
76
+ close (null , objects );
77
+ }
62
78
79
+ /**
80
+ * Closes all given {@link Closeable}s. If a non-null exception is passed in, or closing a
81
+ * stream causes an exception, throws the exception with other {@link RuntimeException} or
82
+ * {@link IOException} exceptions added as suppressed.
83
+ *
84
+ * @param ex existing Exception to add exceptions occurring during close to
85
+ * @param objects objects to close
86
+ *
87
+ * @see #close(Closeable...)
88
+ */
89
+ public static void close (final Exception ex , final Iterable <? extends Closeable > objects ) throws IOException {
90
+ Exception firstException = ex ;
63
91
for (final Closeable object : objects ) {
64
92
try {
65
93
if (object != null ) {
66
94
object .close ();
67
95
}
68
96
} catch (final IOException | RuntimeException e ) {
69
- if (ex == null ) {
70
- ex = e ;
97
+ if (firstException == null ) {
98
+ firstException = e ;
71
99
} else {
72
- ex .addSuppressed (e );
100
+ firstException .addSuppressed (e );
73
101
}
74
102
}
75
103
}
76
104
77
- if (ex != null ) {
78
- if (ex instanceof IOException ) {
79
- throw (IOException ) ex ;
105
+ if (firstException != null ) {
106
+ if (firstException instanceof IOException ) {
107
+ throw (IOException ) firstException ;
80
108
} else {
81
109
// since we only assigned an IOException or a RuntimeException to ex above, in this case ex must be a RuntimeException
82
- throw (RuntimeException ) ex ;
110
+ throw (RuntimeException ) firstException ;
83
111
}
84
112
}
85
113
}
0 commit comments