On 23 Apr 2015, at 22:24, Roger Riggs <roger.ri...@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; }