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.hega...@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.