1
1
/*
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.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
@@ -251,6 +251,20 @@ public long transferTo(OutputStream out) throws IOException {
251
251
}
252
252
}
253
253
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
+
254
268
return super .transferTo (out );
255
269
}
256
270
@@ -274,6 +288,25 @@ private static long transfer(FileChannel fc, WritableByteChannel target)
274
288
return pos - initialPos ;
275
289
}
276
290
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
+
277
310
@ Override
278
311
public void close () throws IOException {
279
312
ch .close ();
0 commit comments