--- old/src/java.base/share/classes/java/lang/Readable.java 2017-11-19 09:22:47.000000000 +0100 +++ new/src/java.base/share/classes/java/lang/Readable.java 2017-11-19 09:22:46.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ package java.lang; import java.io.IOException; +import java.nio.CharBuffer; +import java.util.Objects; /** * A {@code Readable} is a source of characters. Characters from @@ -50,4 +52,69 @@ * @throws java.nio.ReadOnlyBufferException if cb is a read only buffer */ public int read(java.nio.CharBuffer cb) throws IOException; + + /** + * Reads all characters from this source and appends them to a destination + * in the order in which they are read. On return, the source of characters + * will be at its end. + *

+ * This method may block indefinitely while reading from the source or + * writing to the destination. If the source or destination is + * {@link AutoCloseable closeable}, then the behavior when either is + * asynchronously closed, or the thread is interrupted during the + * transfer, is highly implementation-dependent and therefore unspecified. + *

+ * If an I/O error occurs during the operation, then not all characters + * might have been transferred and the source or destination could be + * left in an inconsistent state. The caller of this method should therefore + * ensure in such a case that measures are taken to release any resources + * held by the source and destination. + *

+ * If the destination is capacity bounded and has insufficient capacity to + * append all characters read from the source then the exception may be + * thrown after transferring some characters to the destination. + * + * @implSpec + * The default implementation invokes the read method to read all characters + * from this source and invokes the {@link Appendable#append(CharSequence, int, int)} + * method to write all characters to the appendable. + * + * The default implementation behaves as if: + *

{@code
+     *     long transferred = 0;
+     *     CharBuffer buffer = CharBuffer.allocate(8192);
+     *     int read;
+     *     while ((read = this.read(buffer)) >= 0) {
+     *         buffer.rewind();
+     *         out.append(buffer, 0, read);
+     *         transferred += read;
+     *     }
+     *     return transferred;
+     * }
+ * + * @implNote + * The default implementation should usually be overridden in cases where + * the implementer is already a {@link CharSequence} or its data is already + * available in the internal representation to avoid the extra overhead of + * a buffer in order to transfer its data to the destination. + * + * @param out the appendable, non-null + * @return the number of characters transferred + * @throws IOException if an I/O error occurs when reading or writing + * @throws NullPointerException if {@code out} is {@code null} + * + * @since 10 + */ + public default long transferTo(Appendable out) throws IOException { + Objects.requireNonNull(out, "out"); + long transferred = 0; + CharBuffer buffer = CharBuffer.allocate(8192); + int read; + while ((read = this.read(buffer)) >= 0) { + buffer.rewind(); + out.append(buffer, 0, read); + transferred += read; + } + return transferred; + } }