Skip to content

Commit 40aea04

Browse files
mkargBrian Burkhalter
authored and
Brian Burkhalter
committed
8278268: (ch) InputStream returned by Channels.newInputStream should have fast path for FileChannel targets
Reviewed-by: bpb
1 parent 9b9b5a7 commit 40aea04

File tree

6 files changed

+619
-264
lines changed

6 files changed

+619
-264
lines changed

src/java.base/share/classes/sun/nio/ch/ChannelInputStream.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
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

Comments
 (0)