11/*
2- * Copyright (c) 2001, 2022 , Oracle and/or its affiliates. All rights reserved.
2+ * Copyright (c) 2001, 2023 , Oracle and/or its affiliates. All rights reserved.
33 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44 *
55 * This code is free software; you can redistribute it and/or modify it
@@ -251,6 +251,20 @@ public long transferTo(OutputStream out) throws IOException {
251251 }
252252 }
253253
254+ if (out instanceof ChannelOutputStream cos && cos .channel () instanceof FileChannel fc ) {
255+ ReadableByteChannel rbc = ch ;
256+
257+ if (rbc instanceof SelectableChannel sc ) {
258+ synchronized (sc .blockingLock ()) {
259+ if (!sc .isBlocking ())
260+ throw new IllegalBlockingModeException ();
261+ return transfer (rbc , fc );
262+ }
263+ }
264+
265+ return transfer (rbc , fc );
266+ }
267+
254268 return super .transferTo (out );
255269 }
256270
@@ -274,6 +288,25 @@ private static long transfer(FileChannel fc, WritableByteChannel target)
274288 return pos - initialPos ;
275289 }
276290
291+ /**
292+ * Transfers all bytes from a readable byte channel to a target channel's file.
293+ * If the readable byte channel is a selectable channel then it must be in
294+ * blocking mode.
295+ */
296+ private static long transfer (ReadableByteChannel src , FileChannel dst ) throws IOException {
297+ long initialPos = dst .position ();
298+ long pos = initialPos ;
299+ try {
300+ long n ;
301+ while ((n = dst .transferFrom (src , pos , Long .MAX_VALUE )) > 0 ) {
302+ pos += n ;
303+ }
304+ } finally {
305+ dst .position (pos );
306+ }
307+ return pos - initialPos ;
308+ }
309+
277310 @ Override
278311 public void close () throws IOException {
279312 ch .close ();
0 commit comments