This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-net.git


The following commit(s) were added to refs/heads/master by this push:
     new 3be2077c Reimplement Util.copyStream() with IOUtils.copyLarge()
3be2077c is described below

commit 3be2077ccf1da69614a7883ed352037e30f3366f
Author: Gary Gregory <[email protected]>
AuthorDate: Fri Mar 13 08:42:31 2026 -0400

    Reimplement Util.copyStream() with IOUtils.copyLarge()
    
    Bump Util.DEFAULT_COPY_BUFFER_SIZE from 1 KiB to 8 KiB.
---
 src/changes/changes.xml                           |  1 +
 src/main/java/org/apache/commons/net/io/Util.java | 44 ++++++-----------------
 2 files changed, 12 insertions(+), 33 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 41c03c5c..ed1cc581 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -82,6 +82,7 @@ The <action> type attribute can be add,update,fix,remove.
       <action type="update" dev="ggregory" due-to="Gary Gregory, 
Dependabot">Bump org.apache.commons:commons-parent from 85 to 97 #371, #388, 
#389.</action>
       <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>
       <action type="update" dev="ggregory" due-to="Gary Gregory">Bump 
commons-io:commons-io from 2.20.0 to 2.21.0.</action>
+      <action type="update" dev="ggregory" due-to="Gary Gregory">Bump 
Util.DEFAULT_COPY_BUFFER_SIZE from 1 KiB to 8 KiB.</action>
     </release>
     <release version="3.12.0" date="2025-07-28" description="This is a feature 
and maintenance release. Java 8 or later is required.">
       <!-- FIX -->
diff --git a/src/main/java/org/apache/commons/net/io/Util.java 
b/src/main/java/org/apache/commons/net/io/Util.java
index 1523e066..b669af2a 100644
--- a/src/main/java/org/apache/commons/net/io/Util.java
+++ b/src/main/java/org/apache/commons/net/io/Util.java
@@ -28,14 +28,15 @@ import java.io.Reader;
 import java.io.Writer;
 import java.net.Socket;
 import java.nio.charset.Charset;
+import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.output.ProxyOutputStream;
 import org.apache.commons.net.util.NetConstants;
 
 /**
  * The Util class cannot be instantiated and stores short static convenience 
methods that are often quite useful.
  *
- *
  * @see CopyStreamException
  * @see CopyStreamListener
  * @see CopyStreamAdapter
@@ -46,7 +47,7 @@ public final class Util {
      * The default buffer size ({@value}) used by {@link #copyStream 
copyStream} and {@link #copyReader copyReader} and by the copyReader/copyStream 
methods if
      * a zero or negative buffer size is supplied.
      */
-    public static final int DEFAULT_COPY_BUFFER_SIZE = 1024;
+    public static final int DEFAULT_COPY_BUFFER_SIZE = 
IOUtils.DEFAULT_BUFFER_SIZE;
 
     /**
      * Closes the object quietly, catching rather than throwing IOException. 
Intended for use from finally blocks.
@@ -239,45 +240,22 @@ public final class Util {
      */
     public static long copyStream(final InputStream source, final OutputStream 
dest, final int bufferSize, final long streamSize,
             final CopyStreamListener listener, final boolean flush) throws 
CopyStreamException {
-        int numBytes;
-        long total = 0;
-        final byte[] buffer = new byte[bufferSize > 0 ? bufferSize : 
DEFAULT_COPY_BUFFER_SIZE];
-
+        final AtomicLong total = new AtomicLong();
         try {
-            while ((numBytes = source.read(buffer)) != NetConstants.EOS) {
-                // Technically, some read(byte[]) methods may return 0, and we 
cannot
-                // accept that as an indication of EOF.
+            return IOUtils.copyLarge(source, listener == null ? dest : new 
ProxyOutputStream(dest) {
 
-                if (numBytes == 0) {
-                    final int singleByte = source.read();
-                    if (singleByte < 0) {
-                        break;
-                    }
-                    dest.write(singleByte);
+                @Override
+                protected void afterWrite(int n) throws IOException {
                     if (flush) {
                         dest.flush();
                     }
-                    ++total;
-                    if (listener != null) {
-                        listener.bytesTransferred(total, 1, streamSize);
-                    }
-                    continue;
+                    listener.bytesTransferred(total.addAndGet(n), n, 
streamSize);
                 }
 
-                dest.write(buffer, 0, numBytes);
-                if (flush) {
-                    dest.flush();
-                }
-                total += numBytes;
-                if (listener != null) {
-                    listener.bytesTransferred(total, numBytes, streamSize);
-                }
-            }
-        } catch (final IOException e) {
-            throw new CopyStreamException("IOException caught while copying.", 
total, e);
+            }, new byte[bufferSize > 0 ? bufferSize : 
DEFAULT_COPY_BUFFER_SIZE]);
+        } catch (IOException e) {
+            throw new CopyStreamException("IOException caught while copying.", 
total.get(), e);
         }
-
-        return total;
     }
 
     /**

Reply via email to