Skip to content

Commit 14d6f4c

Browse files
author
Gary Gregory
committed
[IO-636]
- Add and reuse org.apache.commons.io.IOUtils.closeQuitely(Closeable, Consumer<IOException>). - [IO-636] Add and reuse org.apache.commons.io.IOUtils.close(Closeable, IOConsumer<IOException>).
1 parent 86e60dd commit 14d6f4c

9 files changed

Lines changed: 95 additions & 27 deletions

File tree

src/changes/changes.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,8 @@ The <action> type attribute can be add,update,fix,remove.
162162
Add org.apache.commons.io.IOUtils.close(Closeable).
163163
</action>
164164
<action issue="IO-636" dev="ggregory" type="add" due-to="Gary Gregory">
165-
Add and reuse org.apache.commons.io.IOUtils.close(Closeable, Consumer&lt;IOException&gt;)
165+
Add and reuse org.apache.commons.io.IOUtils.closeQuitely(Closeable, Consumer&lt;IOException&gt;).
166+
Add and reuse org.apache.commons.io.IOUtils.close(Closeable, IOConsumer&lt;IOException&gt;).
166167
</action>
167168
</release>
168169

src/main/java/org/apache/commons/io/FileUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1847,7 +1847,7 @@ public static LineIterator lineIterator(final File file, final String encoding)
18471847
inputStream = openInputStream(file);
18481848
return IOUtils.lineIterator(inputStream, encoding);
18491849
} catch (final IOException | RuntimeException ex) {
1850-
IOUtils.close(inputStream, e -> ex.addSuppressed(e));
1850+
IOUtils.closeQuietly(inputStream, e -> ex.addSuppressed(e));
18511851
throw ex;
18521852
}
18531853
}

src/main/java/org/apache/commons/io/IOUtils.java

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import java.util.Objects;
5151
import java.util.function.Consumer;
5252

53+
import org.apache.commons.io.function.IOConsumer;
5354
import org.apache.commons.io.output.AppendableWriter;
5455
import org.apache.commons.io.output.ByteArrayOutputStream;
5556
import org.apache.commons.io.output.StringBuilderWriter;
@@ -113,28 +114,28 @@ public class IOUtils {
113114
* The system directory separator character.
114115
*/
115116
public static final char DIR_SEPARATOR = File.separatorChar;
116-
117+
117118
/**
118119
* The Unix directory separator character.
119120
*/
120121
public static final char DIR_SEPARATOR_UNIX = '/';
121-
122+
122123
/**
123124
* The Windows directory separator character.
124125
*/
125126
public static final char DIR_SEPARATOR_WINDOWS = '\\';
126-
127+
127128
/**
128129
* Represents the end-of-file (or stream).
129130
* @since 2.5 (made public)
130131
*/
131132
public static final int EOF = -1;
132-
133+
133134
/**
134135
* The system line separator string.
135136
*/
136137
public static final String LINE_SEPARATOR;
137-
138+
138139
/**
139140
* The Unix line separator string.
140141
*/
@@ -164,7 +165,7 @@ public class IOUtils {
164165
* did not create a smaller one)
165166
*/
166167
private static char[] SKIP_CHAR_BUFFER;
167-
168+
168169
static {
169170
// avoid security issues
170171
try (final StringBuilderWriter buf = new StringBuilderWriter(4);
@@ -343,7 +344,26 @@ public static BufferedWriter buffer(final Writer writer, final int size) {
343344
*/
344345
@Deprecated
345346
public static void closeQuietly(final Closeable closeable) {
346-
close(closeable, null);
347+
closeQuietly(closeable, (Consumer<IOException>) null);
348+
}
349+
350+
/**
351+
* Closes the given {@link Closeable} as a null-safe operation while consuming IOException by the given {@code consumer}.
352+
*
353+
* @param closeable The resource to close, may be null.
354+
* @param consumer Consumes the IOException thrown by {@link Closeable#close()}.
355+
* @since 2.7
356+
*/
357+
public static void closeQuietly(final Closeable closeable, final Consumer<IOException> consumer) {
358+
if (closeable != null) {
359+
try {
360+
closeable.close();
361+
} catch (IOException e) {
362+
if (consumer != null) {
363+
consumer.accept(e);
364+
}
365+
}
366+
}
347367
}
348368

349369
/**
@@ -364,9 +384,10 @@ public static void close(final Closeable closeable) throws IOException {
364384
*
365385
* @param closeable The resource to close, may be null.
366386
* @param consumer Consume the IOException thrown by {@link Closeable#close()}.
387+
* @throws IOException if an I/O error occurs.
367388
* @since 2.7
368389
*/
369-
public static void close(final Closeable closeable, final Consumer<IOException> consumer) {
390+
public static void close(final Closeable closeable, final IOConsumer<IOException> consumer) throws IOException {
370391
if (closeable != null) {
371392
try {
372393
closeable.close();

src/main/java/org/apache/commons/io/LineIterator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public boolean hasNext() {
103103
}
104104
}
105105
} catch(final IOException ioe) {
106-
IOUtils.close(this, e -> ioe.addSuppressed(e));
106+
IOUtils.closeQuietly(this, e -> ioe.addSuppressed(e));
107107
throw new IllegalStateException(ioe);
108108
}
109109
}

src/main/java/org/apache/commons/io/file/PathUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public static PathCounters copyDirectory(final Path sourceDirectory, final Path
6565

6666
/**
6767
* Copies a file to a directory.
68-
*
68+
*
6969
* @param sourceFile The source file
7070
* @param targetDirectory The target directory.
7171
* @param copyOptions Specifies how the copying should be done.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.commons.io.function;
19+
20+
import java.io.IOException;
21+
import java.util.Objects;
22+
import java.util.function.Consumer;
23+
24+
/**
25+
* Like {@link Consumer} but throws {@link IOException}.
26+
*
27+
* @param <T> the type of the input to the operations.
28+
* @since 2.7
29+
*/
30+
@FunctionalInterface
31+
public interface IOConsumer<T> {
32+
33+
/**
34+
* Performs this operation on the given argument.
35+
*
36+
* @param t the input argument
37+
* @throws IOException if an I/O error occurs.
38+
*/
39+
void accept(T t) throws IOException;
40+
41+
/**
42+
* Returns a composed {@code IoConsumer} that performs, in sequence, this operation followed by the {@code after}
43+
* operation. If performing either operation throws an exception, it is relayed to the caller of the composed
44+
* operation. If performing this operation throws an exception, the {@code after} operation will not be performed.
45+
*
46+
* @param after the operation to perform after this operation
47+
* @return a composed {@code Consumer} that performs in sequence this operation followed by the {@code after}
48+
* operation
49+
* @throws NullPointerException if {@code after} is null
50+
*/
51+
default IOConsumer<T> andThen(IOConsumer<? super T> after) {
52+
Objects.requireNonNull(after);
53+
return (T t) -> {
54+
accept(t);
55+
after.accept(t);
56+
};
57+
}
58+
}

src/main/java/org/apache/commons/io/input/ProxyInputStream.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,7 @@ public int available() throws IOException {
144144
*/
145145
@Override
146146
public void close() throws IOException {
147-
try {
148-
in.close();
149-
} catch (final IOException e) {
150-
handleIOException(e);
151-
}
147+
IOUtils.close(in, e -> handleIOException(e));
152148
}
153149

154150
/**

src/main/java/org/apache/commons/io/output/ProxyOutputStream.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,7 @@ public void flush() throws IOException {
114114
*/
115115
@Override
116116
public void close() throws IOException {
117-
try {
118-
out.close();
119-
} catch (final IOException e) {
120-
handleIOException(e);
121-
}
117+
IOUtils.close(out, e -> handleIOException(e));
122118
}
123119

124120
/**

src/main/java/org/apache/commons/io/output/ProxyWriter.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -205,11 +205,7 @@ public void flush() throws IOException {
205205
*/
206206
@Override
207207
public void close() throws IOException {
208-
try {
209-
out.close();
210-
} catch (final IOException e) {
211-
handleIOException(e);
212-
}
208+
IOUtils.close(out, e -> handleIOException(e));
213209
}
214210

215211
/**

0 commit comments

Comments
 (0)