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 3373d77d Reimplement Util.copyReader() with IOUtils.copyLarge()
3373d77d is described below

commit 3373d77db2376665a034e753e3646251b3d23aa4
Author: Gary Gregory <[email protected]>
AuthorDate: Fri Mar 13 09:03:40 2026 -0400

    Reimplement Util.copyReader() with IOUtils.copyLarge()
---
 src/changes/changes.xml                           |  2 ++
 src/main/java/org/apache/commons/net/io/Util.java | 42 ++++++-----------------
 2 files changed, 13 insertions(+), 31 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index ed1cc581..b18ee03f 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -75,6 +75,8 @@ The <action> type attribute can be add,update,fix,remove.
       <action type="fix" dev="ggregory" due-to="Gary 
Gregory">ListenerList.removeListener(T) now ignores null input to avoid a 
NullPointerException.</action>
       <action type="fix" dev="ggregory" due-to="Gary 
Gregory">ListenerList.addListener(T) now ignores null input.</action>
       <action type="fix" dev="ggregory" due-to="Gary Gregory">Fix typo in 
FTPConnectionClosedException message from FTP.getReply(boolean).</action>
+      <action type="fix" dev="ggregory" due-to="Gary Gregory">Reimplement 
Util.copyReader() with IOUtils.copyLarge().</action>
+      <action type="fix" dev="ggregory" due-to="Gary Gregory">Reimplement 
Util.copyStream() with IOUtils.copyLarge().</action>
       <!-- ADD -->
       <action type="add" dev="ggregory" due-to="Gary Gregory">Add 
DatagramSocketClient.getDefaultTimeoutDuration() and deprecate 
getDefaultTimeout().</action>
       <action type="add" dev="ggregory" due-to="Maros Orsak, Gary Gregory" 
issue="NET-741">Add subnet IPv6 handling with SubnetUtils6 #391.</action>
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 b669af2a..cc1e6221 100644
--- a/src/main/java/org/apache/commons/net/io/Util.java
+++ b/src/main/java/org/apache/commons/net/io/Util.java
@@ -32,7 +32,7 @@ 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;
+import org.apache.commons.io.output.ProxyWriter;
 
 /**
  * The Util class cannot be instantiated and stores short static convenience 
methods that are often quite useful.
@@ -110,6 +110,7 @@ public final class Util {
      * <p>
      * The contents of the Reader are read until its end is reached, but 
neither the source nor the destination are closed. You must do this yourself 
outside
      * the method call. The number of characters read/written is returned.
+     * </p>
      *
      * @param source     The source Reader.
      * @param dest       The destination writer.
@@ -125,40 +126,19 @@ public final class Util {
      */
     public static long copyReader(final Reader source, final Writer dest, 
final int bufferSize, final long streamSize, final CopyStreamListener listener)
             throws CopyStreamException {
-        int numChars;
-        long total = 0;
-        final char[] buffer = new char[bufferSize > 0 ? bufferSize : 
DEFAULT_COPY_BUFFER_SIZE];
-
+        final AtomicLong total = new AtomicLong();
         try {
-            while ((numChars = source.read(buffer)) != NetConstants.EOS) {
-                // Technically, some read(char[]) methods may return 0, and we 
cannot
-                // accept that as an indication of EOF.
-                if (numChars == 0) {
-                    final int singleChar = source.read();
-                    if (singleChar < 0) {
-                        break;
-                    }
-                    dest.write(singleChar);
-                    dest.flush();
-                    ++total;
-                    if (listener != null) {
-                        listener.bytesTransferred(total, 1, streamSize);
-                    }
-                    continue;
-                }
+            return IOUtils.copyLarge(source, listener == null ? dest : new 
ProxyWriter(dest) {
 
-                dest.write(buffer, 0, numChars);
-                dest.flush();
-                total += numChars;
-                if (listener != null) {
-                    listener.bytesTransferred(total, numChars, streamSize);
+                @Override
+                protected void afterWrite(int n) throws IOException {
+                    dest.flush();
+                    listener.bytesTransferred(total.addAndGet(n), n, 
streamSize);
                 }
-            }
-        } catch (final IOException e) {
-            throw new CopyStreamException("IOException caught while copying.", 
total, e);
+            }, new char[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