8246739: InputStream.skipNBytes could be implemented more efficiently

Reviewed-by: rriggs, lancea, naoto
This commit is contained in:
Brian Burkhalter 2020-12-01 20:07:53 +00:00
parent 56b15fbbcc
commit c5046ca5b3

View File

@ -577,13 +577,15 @@ public abstract class InputStream implements Closeable {
* @implSpec * @implSpec
* If {@code n} is zero or negative, then no bytes are skipped. * If {@code n} is zero or negative, then no bytes are skipped.
* If {@code n} is positive, the default implementation of this method * If {@code n} is positive, the default implementation of this method
* invokes {@link #skip(long) skip()} with parameter {@code n}. If the * invokes {@link #skip(long) skip()} repeatedly with its parameter equal
* return value of {@code skip(n)} is non-negative and less than {@code n}, * to the remaining number of bytes to skip until the requested number
* then {@link #read()} is invoked repeatedly until the stream is {@code n} * of bytes has been skipped or an error condition occurs. If at any
* bytes beyond its position when this method was invoked or end of stream * point the return value of {@code skip()} is negative or greater than the
* is reached. If the return value of {@code skip(n)} is negative or * remaining number of bytes to be skipped, then an {@code IOException} is
* greater than {@code n}, then an {@code IOException} is thrown. Any * thrown. If {@code skip()} ever returns zero, then {@link #read()} is
* exception thrown by {@code skip()} or {@code read()} will be propagated. * invoked to read a single byte, and if it returns {@code -1}, then an
* {@code EOFException} is thrown. Any exception thrown by {@code skip()}
* or {@code read()} will be propagated.
* *
* @param n the number of bytes to be skipped. * @param n the number of bytes to be skipped.
* @throws EOFException if end of stream is encountered before the * @throws EOFException if end of stream is encountered before the
@ -596,20 +598,19 @@ public abstract class InputStream implements Closeable {
* @since 12 * @since 12
*/ */
public void skipNBytes(long n) throws IOException { public void skipNBytes(long n) throws IOException {
if (n > 0) { while (n > 0) {
long ns = skip(n); long ns = skip(n);
if (ns >= 0 && ns < n) { // skipped too few bytes if (ns > 0 && ns <= n) {
// adjust number to skip // adjust number to skip
n -= ns; n -= ns;
// read until requested number skipped or EOS reached } else if (ns == 0) { // no bytes skipped
while (n > 0 && read() != -1) { // read one byte to check for EOS
n--; if (read() == -1) {
}
// if not enough skipped, then EOFE
if (n != 0) {
throw new EOFException(); throw new EOFException();
} }
} else if (ns != n) { // skipped negative or too many bytes // one byte read so decrement number to skip
n--;
} else { // skipped negative or too many bytes
throw new IOException("Unable to skip exactly"); throw new IOException("Unable to skip exactly");
} }
} }