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

Roger Riggs Roger.Riggs at Oracle.com
Fri May 1 14:20:02 UTC 2015


Hi Chris,

There is some duplication in the descriptions of the buffer contents; 
see below.

On 5/1/2015 5:54 AM, Chris Hegarty wrote:
> This latest version addresses all comments so far:
>
> /**
>  * 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, 
> 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.
>  * 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. _
This section duplicates the previous sentence and the following sentence.
>  *
>  * <p> In the case where {@code off > 0}, elements {@code b[0]} through
>  * {@code b[off-1]} are unaffected. In every case, elements
>  * {@code b[off+len]} through {@code b[b.length-1]} are unaffected.
>  *
> _ * <p> In every case, elements {@code b[0]} through {@code b[off-1]} 
> and __
> __ * elements {@code b[off+len]} through {@code b[b.length-1]} are 
> unaffected. _
Duplicates previous paragraph.

Each section of the buffer should be described only once.

Regards, Roger

>  *
>  * <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 _occur _do
>  * so__after some, but not all, bytes of {@code b} have been updated with
>  * data from the input stream. Consequently the input stream and 
> {@code b}
>  * 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 readNBytes(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.
>
> On 24/04/15 09:44, Chris Hegarty wrote:
>> On 23 Apr 2015, at 22:24, Roger Riggs <Roger.Riggs at oracle.com> wrote:
>>
>>> Hi Pavel,
>>>
>>> On 4/23/2015 5:12 PM, Pavel Rappo wrote:
>>>> Hey Roger,
>>>>
>>>> 1. Good catch! This thing also applies to 
>>>> java.io.InputStream.read(byte[], int, int):
>>
>> Yes, good catch indeed.
>>
>>>>       * <p> In every case, elements <code>b[0]</code> through
>>>>       * <code>b[off]</code> and elements <code>b[off+len]</code> 
>>>> through
>>>>       * <code>b[b.length-1]</code> are unaffected.
>>>>
>>>> I suppose the javadoc for the method proposed by Chris has started 
>>>> its life as a
>>>> copy of the javadoc read(byte[], int, int) which was assumed to be 
>>>> perfectly
>>>> polished. Unfortunately it was a false assumption.
>>> it happens...  many many people have read those descriptions (or 
>>> didn't because
>>> it was too obvious or thought to be redundant).
>>
>> I propose this small amendment.
>>
>> * <p> In the case where {@code off > 0}, elements {@code b[0]} through
>> * {@code b[off-1]} are unaffected. In every case, elements
>> * {@code b[off+len]} through {@code b[b.length-1]} are unaffected.
>>
>>>>
>>>> 2. About awkward sentences. This paragraph also has to be rephrased 
>>>> for the same reason:
>>>>
>>>>       * <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.
>>>>
>>>> If k == 0 then spec claims to store values in b[off]... b[off - 1].
>>
>> Reading the whole method description leads to be believe that 'k' 
>> cannot equal 0 at this point. The previous paragraph handles the case 
>> where len is 0. The previous paragraph to that handles the EOF case. 
>> This paragraph implicitly implies that k is greater than 0, “The 
>> first byte read”, and “the number of actual bytes read”, neither of 
>> which can be 0 at this point.
>>
>> I included below [*] the latest version of this method, including all 
>> comments so far.
>>
>>> If one concludes that's an empty interval then its ok; it just reads 
>>> oddly and can
>>> make the reader think its wrong.
>>> In some cases it is easier if the upper bound is defined to be 
>>> exclusive.
>>> Then if lower == upper, its empty.
>>>
>>> If better language were constructed for the new method then perhaps 
>>> it could
>>> be worked back into methods with similar behavior later.  If the 
>>> wording changes
>>> in any significant way, the conformance team will have to go back 
>>> and re-evaluate
>>> it in detail to see if it really has changed.  So I'd leave it alone.
>>>
>>> Roger
>>
>> -Chris.
>>
>> [*]
>>
>> /**
>>   * 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, 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.
>>   * 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 the case where {@code off > 0}, elements {@code b[0]} through
>>   * {@code b[off-1]} are unaffected. In every case, elements
>>   * {@code b[off+len]} through {@code b[b.length-1]} are unaffected.
>>   *
>>   * <p> In every case, elements {@code b[0]} through {@code b[off-1]} 
>> 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, but not all, bytes of {@code b} have been updated 
>> with
>>   * data from the input stream. Consequently the input stream and 
>> {@code b}
>>   * 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 readNBytes(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;
>> }
>>




More information about the core-libs-dev mailing list