2828import java .io .Writer ;
2929import java .net .Socket ;
3030import java .nio .charset .Charset ;
31+ import java .util .concurrent .atomic .AtomicLong ;
3132
3233import org .apache .commons .io .IOUtils ;
34+ import org .apache .commons .io .output .ProxyOutputStream ;
3335import 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