< prev index next >

src/java.base/share/classes/java/io/InputStream.java

Print this page

        

@@ -61,11 +61,12 @@
      * {@code close()} method.  Subsequent calls to {@code close()} have no
      * effect.
      *
      * <p> While the stream is open, the {@code available()}, {@code read()},
      * {@code read(byte[])}, {@code read(byte[], int, int)},
-     * {@code readAllBytes()}, {@code readNBytes()}, {@code skip()}, and
+     * {@code readAllBytes()}, {@code readNBytes(byte[], int, int)},
+     * {@code readNBytes(int)}, {@code skip()}, and
      * {@code transferTo()} methods all behave as if end of stream has been
      * reached.  After the stream has been closed, these methods all throw
      * {@code IOException}.
      *
      * <p> The {@code markSupported()} method returns {@code false}.  The

@@ -121,10 +122,20 @@
                 ensureOpen();
                 return 0;
             }
 
             @Override
+            public byte[] readNBytes(int len)
+                throws IOException {
+                if (len < 0) {
+                    throw new IllegalArgumentException("len < 0");
+                }
+                ensureOpen();
+                return new byte[0];
+            }
+
+            @Override
             public long skip(long n) throws IOException {
                 ensureOpen();
                 return 0L;
             }
 

@@ -231,12 +242,12 @@
      * <code>IOException</code>, the exception is caught and treated as if it
      * were end of file; the bytes read up to that point are stored into
      * <code>b</code> and the number of bytes read before the exception
      * occurred is returned. The default implementation of this method blocks
      * until the requested amount of input data <code>len</code> has been read,
-     * end of file is detected, or an exception is thrown. Subclasses are encouraged
-     * to provide a more efficient implementation of this method.
+     * end of file is detected, or an exception is thrown. Subclasses are
+     * encouraged to provide a more efficient implementation of this method.
      *
      * @param      b     the buffer into which the data is read.
      * @param      off   the start offset in array <code>b</code>
      *                   at which the data is written.
      * @param      len   the maximum number of bytes to read.

@@ -285,20 +296,26 @@
      * OutOfMemoryError: Requested array size exceeds VM limit
      */
     private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
 
     /**
-     * Reads all remaining bytes from the input stream. This method blocks until
-     * all remaining bytes have been read and end of stream is detected, or an
-     * exception is thrown. This method does not close the input stream.
+     * Reads a number of bytes from the input stream. The number of bytes to
+     * read is specified by the {@code len} parameter which is interpreted as
+     * an inclusive upper bound on the number to read. This method blocks
+     * until the requested number of bytes have been read, end of stream is
+     * detected, or an exception is thrown. This method does not close the
+     * input stream.
+     *
+     * <p> If {@code len} is zero, then no bytes are read and an empty byte
+     * array is returned.
      *
      * <p> When this stream reaches end of stream, further invocations of this
      * method will return an empty byte array.
      *
      * <p> Note that this method is intended for simple cases where it is
-     * convenient to read all bytes into a byte array. It is not intended for
-     * reading input streams with large amounts of data.
+     * convenient to read the specified number of bytes into a byte array. It
+     * is not intended for reading large amounts of data.
      *
      * <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.
      *

@@ -306,30 +323,40 @@
      * so after some, but not all, bytes have been read. Consequently the input
      * stream may not be at end of stream and may be in an inconsistent state.
      * It is strongly recommended that the stream be promptly closed if an I/O
      * error occurs.
      *
+     * @param len the maximum number of bytes to read
      * @return a byte array containing the bytes read from this input stream
+     * @throws IllegalArgumentException if {@code len} is negative
      * @throws IOException if an I/O error occurs
      * @throws OutOfMemoryError if an array of the required size cannot be
      *         allocated. For example, if an array larger than {@code 2GB} would
      *         be required to store the bytes.
      *
-     * @since 9
+     * @since 11
      */
-    public byte[] readAllBytes() throws IOException {
+    private byte[] readAtMostNBytes(int len)
+        throws IOException {
+        if (len < 0) {
+            throw new IllegalArgumentException("len < 0");
+        }
+
         List<byte[]> bufs = null;
         byte[] result = null;
         int total = 0;
+        int remaining = len;
         int n;
         do {
-            byte[] buf = new byte[DEFAULT_BUFFER_SIZE];
+            byte[] buf = new byte[Math.min(len, DEFAULT_BUFFER_SIZE)];
             int nread = 0;
 
             // read to EOF which may read more or less than buffer size
-            while ((n = read(buf, nread, buf.length - nread)) > 0) {
+            while ((n = read(buf, nread,
+                Math.min(buf.length - nread, remaining))) > 0) {
                 nread += n;
+                remaining -= n;
             }
 
             if (nread > 0) {
                 if (MAX_BUFFER_SIZE - total < nread) {
                     throw new OutOfMemoryError("Required array size too large");

@@ -343,11 +370,13 @@
                         bufs.add(result);
                     }
                     bufs.add(buf);
                 }
             }
-        } while (n >= 0); // if the last call to read returned -1, then break
+            // if the last call to read returned -1 or the number of bytes
+            // requested have been read then break
+        } while (n >= 0 && remaining > 0);
 
         if (bufs == null) {
             if (result == null) {
                 return new byte[0];
             }

@@ -355,22 +384,99 @@
                 result : Arrays.copyOf(result, total);
         }
 
         result = new byte[total];
         int offset = 0;
-        int remaining = total;
+        remaining = total;
         for (byte[] b : bufs) {
-            int len = Math.min(b.length, remaining);
-            System.arraycopy(b, 0, result, offset, len);
-            offset += len;
-            remaining -= len;
+            int count = Math.min(b.length, remaining);
+            System.arraycopy(b, 0, result, offset, count);
+            offset += count;
+            remaining -= count;
         }
 
         return result;
     }
 
     /**
+     * Reads all remaining bytes from the input stream. This method blocks until
+     * all remaining bytes have been read and end of stream is detected, or an
+     * exception is thrown. This method does not close the input stream.
+     *
+     * <p> When this stream reaches end of stream, further invocations of this
+     * method will return an empty byte array.
+     *
+     * <p> Note that this method is intended for simple cases where it is
+     * convenient to read all bytes into a byte array. It is not intended for
+     * reading input streams with large amounts of data.
+     *
+     * <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 have been read. Consequently the input
+     * stream may not be at end of stream and may be in an inconsistent state.
+     * It is strongly recommended that the stream be promptly closed if an I/O
+     * error occurs.
+     *
+     * @return a byte array containing the bytes read from this input stream
+     * @throws IOException if an I/O error occurs
+     * @throws OutOfMemoryError if an array of the required size cannot be
+     *         allocated. For example, if an array larger than {@code 2GB} would
+     *         be required to store the bytes.
+     *
+     * @since 9
+     */
+    public byte[] readAllBytes() throws IOException {
+        return readAtMostNBytes(Integer.MAX_VALUE);
+    }
+
+    /**
+     * Reads up to a specified number of bytes from the input stream. This
+     * method blocks until the requested number of bytes have been read, end
+     * of stream is detected, or an exception is thrown. This method does not
+     * close the input stream.
+     *
+     * <p> The length of the returned array equals the number of bytes read
+     * from the stream. If {@code len} is zero, then no bytes are read and
+     * an empty byte array is returned. Otherwise, up to {@code len} bytes
+     * are read from the stream. Fewer than {@code len} bytes may be read if
+     * end of stream is encountered.
+     *
+     * <p> When this stream reaches end of stream, further invocations of this
+     * method will return an empty byte array.
+     *
+     * <p> Note that this method is intended for simple cases where it is
+     * convenient to read the specified number of bytes into a byte array. It
+     * is not intended for reading large amounts of data.
+     *
+     * <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 have been read. Consequently the input
+     * stream may not be at end of stream and may be in an inconsistent state.
+     * It is strongly recommended that the stream be promptly closed if an I/O
+     * error occurs.
+     *
+     * @param len the maximum number of bytes to read
+     * @return a byte array containing the bytes read from this input stream
+     * @throws IllegalArgumentException if {@code length} is negative
+     * @throws IOException if an I/O error occurs
+     * @throws OutOfMemoryError if an array of the required size cannot be
+     *         allocated. For example, if an array larger than {@code 2GB} would
+     *         be required to store the bytes.
+     *
+     * @since 11
+     */
+    public byte[] readNBytes(int len) throws IOException {
+        return readAtMostNBytes(len);
+    }
+
+    /**
      * Reads the requested number of 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.
< prev index next >