src/java.base/share/classes/java/io/InputStream.java
changeset 52860 8dd8965df7f6
parent 49238 63eceefeb347
child 54251 51195881bd3a
--- a/src/java.base/share/classes/java/io/InputStream.java	Wed Dec 05 19:17:22 2018 +0100
+++ b/src/java.base/share/classes/java/io/InputStream.java	Wed Dec 05 15:58:46 2018 -0800
@@ -64,8 +64,8 @@
      * <p> While the stream is open, the {@code available()}, {@code read()},
      * {@code read(byte[])}, {@code read(byte[], int, int)},
      * {@code readAllBytes()}, {@code readNBytes(byte[], int, int)},
-     * {@code readNBytes(int)}, {@code skip(long)}, and
-     * {@code transferTo()} methods all behave as if end of stream has been
+     * {@code readNBytes(int)}, {@code skip(long)}, {@code skipNBytes(long)},
+     * 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}.
      *
@@ -139,6 +139,14 @@
             }
 
             @Override
+            public void skipNBytes(long n) throws IOException {
+                ensureOpen();
+                if (n > 0) {
+                    throw new EOFException();
+                }
+            }
+
+            @Override
             public long transferTo(OutputStream out) throws IOException {
                 Objects.requireNonNull(out);
                 ensureOpen();
@@ -513,11 +521,11 @@
      * For instance, the implementation may depend on the ability to seek.
      *
      * @param      n   the number of bytes to be skipped.
-     * @return     the actual number of bytes skipped.
+     * @return     the actual number of bytes skipped which might be zero.
      * @throws     IOException  if an I/O error occurs.
+     * @see        java.io.InputStream#skipNBytes(long)
      */
     public long skip(long n) throws IOException {
-
         long remaining = n;
         int nr;
 
@@ -539,6 +547,65 @@
     }
 
     /**
+     * Skips over and discards exactly {@code n} bytes of data from this input
+     * stream.  If {@code n} is zero, then no bytes are skipped.
+     * If {@code n} is negative, then no bytes are skipped.
+     * Subclasses may handle the negative value differently.
+     *
+     * <p> This method blocks until the requested number of bytes have been
+     * skipped, end of file is reached, or an exception is thrown.
+     *
+     * <p> If end of stream is reached before the stream is at the desired
+     * position, then an {@code EOFException} is thrown.
+     *
+     * <p> If an I/O error occurs, then 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.
+     *
+     * @implNote
+     * Subclasses are encouraged to provide a more efficient implementation
+     * of this method.
+     *
+     * @implSpec
+     * If {@code n} is zero or negative, then no bytes are skipped.
+     * If {@code n} is positive, the default implementation of this method
+     * invokes {@link #skip(long) skip()} with parameter {@code n}.  If the
+     * return value of {@code skip(n)} is non-negative and less than {@code n},
+     * then {@link #read()} is invoked repeatedly until the stream is {@code n}
+     * bytes beyond its position when this method was invoked or end of stream
+     * is reached.  If the return value of {@code skip(n)} is negative or
+     * greater than {@code n}, then an {@code IOException} is thrown.  Any
+     * exception thrown by {@code skip()} or {@code read()} will be propagated.
+     *
+     * @param      n   the number of bytes to be skipped.
+     * @throws     EOFException if end of stream is encountered before the
+     *             stream can be positioned {@code n} bytes beyond its position
+     *             when this method was invoked.
+     * @throws     IOException  if the stream cannot be positioned properly or
+     *             if an I/O error occurs.
+     * @see        java.io.InputStream#skip(long)
+     */
+    public void skipNBytes(long n) throws IOException {
+        if (n > 0) {
+            long ns = skip(n);
+            if (ns >= 0 && ns < n) { // skipped too few bytes
+                // adjust number to skip
+                n -= ns;
+                // read until requested number skipped or EOS reached
+                while (n > 0 && read() != -1) {
+                    n--;
+                }
+                // if not enough skipped, then EOFE
+                if (n != 0) {
+                    throw new EOFException();
+                }
+            } else if (ns != n) { // skipped negative or too many bytes
+                throw new IOException("Unable to skip exactly");
+            }
+        }
+    }
+
+    /**
      * Returns an estimate of the number of bytes that can be read (or skipped
      * over) from this input stream without blocking, which may be 0, or 0 when
      * end of stream is detected.  The read might be on the same thread or