RFR [9] Add blocking bulk read to java.io.InputStream

Pavel Rappo pavel.rappo at oracle.com
Thu Apr 23 11:48:58 UTC 2015


Hi Chris,

The spec looks good. The only single detail I've noticed is that the "an
exception is thrown" as a possible cause of unblocking the method is missing:

--- dev/jdk/src/java.base/share/classes/java/io/InputStream.java   (revision )
+++ dev/jdk/src/java.base/share/classes/java/io/InputStream.java   (revision )
@@ -408,8 +408,9 @@
     /**
      * Reads some bytes from the input stream into the given byte array. This
      * method blocks until {@code len} bytes of input data have been read, or
-     * end of stream is detected. The number of bytes actually read, possibly
-     * zero, is returned. This method does not close the input stream.
+     * end of stream is detected, or an exception is thrown. The number of bytes
+     * actually read, possibly zero, is returned. This method does not close the
+     * input stream.
      *
      * <p> In the case where end of stream is reached before {@code len} bytes
      * have been read, then the actual number of bytes read will be returned.

This fix would be very consistent with other `read` methods of the class.
I'd be happy to write a comprehensive test for the whole thing. Thanks.

-Pavel

> On 23 Apr 2015, at 10:01, Chris Hegarty <chris.hegarty at oracle.com> wrote:
> 
> A while back when we added the long overdue java.io.InputStream.transferTo method, there was support for adding a blocking bulk read operation. This has been sitting in a branch in the sandbox since then. I would like to revive it with the intention of bringing it into 9. The motivation for this addition is provide library support for a common pattern found when reading from input streams.
> 
> /**
> * Reads some bytes from the input stream into the given byte array. This
> * method blocks until {@code len} bytes of input data have been read, or
> * end of stream is detected. The number of bytes actually read, possibly
> * zero, is returned. This method does not close the input stream.
> *
> * <p> In the case where end of stream is reached before {@code len} bytes
> * have been read, then the actual number of bytes read will be returned.
> * When this stream reaches end of stream, further invocations of this
> * method will return zero.
> *
> * <p> If {@code len} is zero, then no bytes are read and {@code 0} is
> * returned; otherwise, there is an attempt to read up to {@code len} bytes.
> *
> * <p> The first byte read is stored into element {@code b[off]}, the next
> * one in to {@code b[off+1]}, and so on. The number of bytes read is, at
> * most, equal to {@code len}. Let <i>k</i> be the number of bytes actually
> * read; these bytes will be stored in elements {@code b[off]} through
> * {@code b[off+}<i>k</i>{@code -1]}, leaving elements {@code b[off+}<i>k</i>
> * {@code ]} through {@code b[off+len-1]} unaffected.
> *
> * <p> In every case, elements {@code b[0]} through {@code b[off]} and
> * elements{@code b[off+len]} through {@code b[b.length-1]} are unaffected.
> *
> * <p> The behavior for the case where the input stream is <i>asynchronously
> * closed</i>, or the thread interrupted during the read, is highly input
> * stream specific, and therefore not specified.
> *
> * <p> If an I/O error occurs reading from the input stream, then it may do
> * so after some bytes have been read. Consequently the input stream may be
> * in an inconsistent state. It is strongly recommended that the stream be
> * promptly closed if an I/O error occurs.
> *
> * @param  b the buffer into which the data is read
> * @param  off the start offset in {@code b} at which the data is written
> * @param  len the maximum number of bytes to read
> * @return the actual number of bytes read into the buffer
> * @throws IOException if an I/O error occurs
> * @throws NullPointerException if {@code b} is {@code null}
> * @throws IndexOutOfBoundsException If {@code off} is negative, {@code len}
> *                is negative, or {@code len} is greater than {@code b.length - off}
> *
> * @since 1.9
> */
> public int readBytes(byte[] b, int off, int len) throws IOException {
>    Objects.requireNonNull(b);
>    if (off < 0 || len < 0 || len > b.length - off)
>        throw new IndexOutOfBoundsException();
>    int n = 0;
>    while (n < len) {
>        int count = read(b, off + n, len - n);
>        if (count < 0)
>            break;
>        n += count;
>    }
>    return n;
> }
> 
> -Chris.




More information about the core-libs-dev mailing list