--- old/src/java.base/share/classes/java/io/InputStream.java 2018-10-23 14:56:28.000000000 -0700 +++ new/src/java.base/share/classes/java/io/InputStream.java 2018-10-23 14:56:27.000000000 -0700 @@ -64,8 +64,8 @@ *
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(); @@ -496,6 +504,44 @@ } /** + * Reads and discards up to {@code n} bytes of data from this input + * stream. If {@code n <= 0}, no bytes are skipped. An + * {@code EOFException} may optionally be thrown if end of stream is + * encountered before the requested number of bytes has been skipped. + * + *
This method blocks until data is available to skip, end of file is
+ * detected, or an exception is thrown.
+ *
+ * @param n the number of bytes to be skipped.
+ * @return the actual number of bytes skipped which might be zero.
+ * @throws EOFException if {@code throwOnEOF} is {@code true} and end
+ * of stream is encountered before {@code n} bytes are skipped.
+ * @throws IOException if an I/O error occurs.
+ */
+ private long discardNBytes(long n, boolean throwOnEOF) throws IOException {
+ if (n <= 0) {
+ return 0;
+ }
+
+ long remaining = n;
+ int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);
+ byte[] skipBuffer = new byte[size];
+
+ while (remaining > 0) {
+ int nr = read(skipBuffer, 0, (int)Math.min(size, remaining));
+ if (nr < 0) {
+ if (throwOnEOF) {
+ throw new EOFException();
+ }
+ break;
+ }
+ remaining -= nr;
+ }
+
+ return n - remaining;
+ }
+
+ /**
* Skips over and discards n
bytes of data from this input
* stream. The skip
method may, for a variety of reasons, end
* up skipping over some smaller number of bytes, possibly 0
.
@@ -513,29 +559,37 @@
* 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.
*/
public long skip(long n) throws IOException {
+ return discardNBytes(n, false);
+ }
- long remaining = n;
- int nr;
-
- if (n <= 0) {
- return 0;
- }
-
- int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);
- byte[] skipBuffer = new byte[size];
- while (remaining > 0) {
- nr = read(skipBuffer, 0, (int)Math.min(size, remaining));
- if (nr < 0) {
- break;
+ /**
+ * Skips over and discards exactly {@code n} bytes of data from this input
+ * stream. If {@code n <= 0}, no bytes are skipped. If {@code n > 0},
+ * then {@code n} bytes of data are skipped unless end of stream is
+ * encountered first, in which case an {@code EOFException} is thrown.
+ *
+ *
This method blocks until data is available to skip, end of file is + * detected, or an exception is thrown. + * + * @param n the number of bytes to be skipped. + * @throws EOFException if end of stream is encountered before {@code n} + * bytes are skipped. + * @throws IOException if an I/O error occurs. + */ + public void skipNBytes(long n) throws IOException { + if (n > 0) { + // Invoke skip() so as to avail of any subclass efficiency + long ns = skip(n); + + // If not enough skipped, read and discard bytes, failing on EOF + if (ns != n) { + discardNBytes(n - ns, true); } - remaining -= nr; } - - return n - remaining; } /**