Skip to content

Commit 3be2077

Browse files
committed
Reimplement Util.copyStream() with IOUtils.copyLarge()
Bump Util.DEFAULT_COPY_BUFFER_SIZE from 1 KiB to 8 KiB.
1 parent 7b41144 commit 3be2077

2 files changed

Lines changed: 12 additions & 33 deletions

File tree

src/changes/changes.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ The <action> type attribute can be add,update,fix,remove.
8282
<action type="update" dev="ggregory" due-to="Gary Gregory, Dependabot">Bump org.apache.commons:commons-parent from 85 to 97 #371, #388, #389.</action>
8383
<action type="update" dev="ggregory" due-to="Gary Gregory, Dependabot">Bump org.apache.commons:commons-lang3 from 3.18.0 to 3.19.0.</action>
8484
<action type="update" dev="ggregory" due-to="Gary Gregory">Bump commons-io:commons-io from 2.20.0 to 2.21.0.</action>
85+
<action type="update" dev="ggregory" due-to="Gary Gregory">Bump Util.DEFAULT_COPY_BUFFER_SIZE from 1 KiB to 8 KiB.</action>
8586
</release>
8687
<release version="3.12.0" date="2025-07-28" description="This is a feature and maintenance release. Java 8 or later is required.">
8788
<!-- FIX -->

src/main/java/org/apache/commons/net/io/Util.java

Lines changed: 11 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,15 @@
2828
import java.io.Writer;
2929
import java.net.Socket;
3030
import java.nio.charset.Charset;
31+
import java.util.concurrent.atomic.AtomicLong;
3132

3233
import org.apache.commons.io.IOUtils;
34+
import org.apache.commons.io.output.ProxyOutputStream;
3335
import org.apache.commons.net.util.NetConstants;
3436

3537
/**
3638
* The Util class cannot be instantiated and stores short static convenience methods that are often quite useful.
3739
*
38-
*
3940
* @see CopyStreamException
4041
* @see CopyStreamListener
4142
* @see CopyStreamAdapter
@@ -46,7 +47,7 @@ public final class Util {
4647
* The default buffer size ({@value}) used by {@link #copyStream copyStream} and {@link #copyReader copyReader} and by the copyReader/copyStream methods if
4748
* a zero or negative buffer size is supplied.
4849
*/
49-
public static final int DEFAULT_COPY_BUFFER_SIZE = 1024;
50+
public static final int DEFAULT_COPY_BUFFER_SIZE = IOUtils.DEFAULT_BUFFER_SIZE;
5051

5152
/**
5253
* Closes the object quietly, catching rather than throwing IOException. Intended for use from finally blocks.
@@ -239,45 +240,22 @@ public static long copyStream(final InputStream source, final OutputStream dest,
239240
*/
240241
public static long copyStream(final InputStream source, final OutputStream dest, final int bufferSize, final long streamSize,
241242
final CopyStreamListener listener, final boolean flush) throws CopyStreamException {
242-
int numBytes;
243-
long total = 0;
244-
final byte[] buffer = new byte[bufferSize > 0 ? bufferSize : DEFAULT_COPY_BUFFER_SIZE];
245-
243+
final AtomicLong total = new AtomicLong();
246244
try {
247-
while ((numBytes = source.read(buffer)) != NetConstants.EOS) {
248-
// Technically, some read(byte[]) methods may return 0, and we cannot
249-
// accept that as an indication of EOF.
245+
return IOUtils.copyLarge(source, listener == null ? dest : new ProxyOutputStream(dest) {
250246

251-
if (numBytes == 0) {
252-
final int singleByte = source.read();
253-
if (singleByte < 0) {
254-
break;
255-
}
256-
dest.write(singleByte);
247+
@Override
248+
protected void afterWrite(int n) throws IOException {
257249
if (flush) {
258250
dest.flush();
259251
}
260-
++total;
261-
if (listener != null) {
262-
listener.bytesTransferred(total, 1, streamSize);
263-
}
264-
continue;
252+
listener.bytesTransferred(total.addAndGet(n), n, streamSize);
265253
}
266254

267-
dest.write(buffer, 0, numBytes);
268-
if (flush) {
269-
dest.flush();
270-
}
271-
total += numBytes;
272-
if (listener != null) {
273-
listener.bytesTransferred(total, numBytes, streamSize);
274-
}
275-
}
276-
} catch (final IOException e) {
277-
throw new CopyStreamException("IOException caught while copying.", total, e);
255+
}, new byte[bufferSize > 0 ? bufferSize : DEFAULT_COPY_BUFFER_SIZE]);
256+
} catch (IOException e) {
257+
throw new CopyStreamException("IOException caught while copying.", total.get(), e);
278258
}
279-
280-
return total;
281259
}
282260

283261
/**

0 commit comments

Comments
 (0)