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