001/* 002 * Copyright (C) 2007 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 005 * in compliance with the License. You may obtain a copy of the License at 006 * 007 * http://www.apache.org/licenses/LICENSE-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, software distributed under the License 010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 011 * or implied. See the License for the specific language governing permissions and limitations under 012 * the License. 013 */ 014 015package com.google.common.io; 016 017import static com.google.common.base.Preconditions.checkArgument; 018import static com.google.common.base.Preconditions.checkNotNull; 019import static com.google.common.base.Preconditions.checkPositionIndex; 020import static com.google.common.base.Preconditions.checkPositionIndexes; 021import static java.lang.Math.max; 022import static java.lang.Math.min; 023 024import com.google.common.annotations.GwtIncompatible; 025import com.google.common.annotations.J2ktIncompatible; 026import com.google.common.math.IntMath; 027import com.google.errorprone.annotations.CanIgnoreReturnValue; 028import java.io.ByteArrayInputStream; 029import java.io.ByteArrayOutputStream; 030import java.io.DataInput; 031import java.io.DataInputStream; 032import java.io.DataOutput; 033import java.io.DataOutputStream; 034import java.io.EOFException; 035import java.io.FilterInputStream; 036import java.io.IOException; 037import java.io.InputStream; 038import java.io.OutputStream; 039import java.nio.ByteBuffer; 040import java.nio.channels.FileChannel; 041import java.nio.channels.ReadableByteChannel; 042import java.nio.channels.WritableByteChannel; 043import java.util.ArrayDeque; 044import java.util.Arrays; 045import java.util.Queue; 046import javax.annotation.CheckForNull; 047import org.checkerframework.checker.nullness.qual.Nullable; 048 049/** 050 * Provides utility methods for working with byte arrays and I/O streams. 051 * 052 * @author Chris Nokleberg 053 * @author Colin Decker 054 * @since 1.0 055 */ 056@J2ktIncompatible 057@GwtIncompatible 058@ElementTypesAreNonnullByDefault 059public final class ByteStreams { 060 061 private static final int BUFFER_SIZE = 8192; 062 063 /** Creates a new byte array for buffering reads or writes. */ 064 static byte[] createBuffer() { 065 return new byte[BUFFER_SIZE]; 066 } 067 068 /** 069 * There are three methods to implement {@link FileChannel#transferTo(long, long, 070 * WritableByteChannel)}: 071 * 072 * <ol> 073 * <li>Use sendfile(2) or equivalent. Requires that both the input channel and the output 074 * channel have their own file descriptors. Generally this only happens when both channels 075 * are files or sockets. This performs zero copies - the bytes never enter userspace. 076 * <li>Use mmap(2) or equivalent. Requires that either the input channel or the output channel 077 * have file descriptors. Bytes are copied from the file into a kernel buffer, then directly 078 * into the other buffer (userspace). Note that if the file is very large, a naive 079 * implementation will effectively put the whole file in memory. On many systems with paging 080 * and virtual memory, this is not a problem - because it is mapped read-only, the kernel 081 * can always page it to disk "for free". However, on systems where killing processes 082 * happens all the time in normal conditions (i.e., android) the OS must make a tradeoff 083 * between paging memory and killing other processes - so allocating a gigantic buffer and 084 * then sequentially accessing it could result in other processes dying. This is solvable 085 * via madvise(2), but that obviously doesn't exist in java. 086 * <li>Ordinary copy. Kernel copies bytes into a kernel buffer, from a kernel buffer into a 087 * userspace buffer (byte[] or ByteBuffer), then copies them from that buffer into the 088 * destination channel. 089 * </ol> 090 * 091 * This value is intended to be large enough to make the overhead of system calls negligible, 092 * without being so large that it causes problems for systems with atypical memory management if 093 * approaches 2 or 3 are used. 094 */ 095 private static final int ZERO_COPY_CHUNK_SIZE = 512 * 1024; 096 097 private ByteStreams() {} 098 099 /** 100 * Copies all bytes from the input stream to the output stream. Does not close or flush either 101 * stream. 102 * 103 * <p><b>Java 9 users and later:</b> this method should be treated as deprecated; use the 104 * equivalent {@link InputStream#transferTo} method instead. 105 * 106 * @param from the input stream to read from 107 * @param to the output stream to write to 108 * @return the number of bytes copied 109 * @throws IOException if an I/O error occurs 110 */ 111 @CanIgnoreReturnValue 112 public static long copy(InputStream from, OutputStream to) throws IOException { 113 checkNotNull(from); 114 checkNotNull(to); 115 byte[] buf = createBuffer(); 116 long total = 0; 117 while (true) { 118 int r = from.read(buf); 119 if (r == -1) { 120 break; 121 } 122 to.write(buf, 0, r); 123 total += r; 124 } 125 return total; 126 } 127 128 /** 129 * Copies all bytes from the readable channel to the writable channel. Does not close or flush 130 * either channel. 131 * 132 * @param from the readable channel to read from 133 * @param to the writable channel to write to 134 * @return the number of bytes copied 135 * @throws IOException if an I/O error occurs 136 */ 137 @CanIgnoreReturnValue 138 public static long copy(ReadableByteChannel from, WritableByteChannel to) throws IOException { 139 checkNotNull(from); 140 checkNotNull(to); 141 if (from instanceof FileChannel) { 142 FileChannel sourceChannel = (FileChannel) from; 143 long oldPosition = sourceChannel.position(); 144 long position = oldPosition; 145 long copied; 146 do { 147 copied = sourceChannel.transferTo(position, ZERO_COPY_CHUNK_SIZE, to); 148 position += copied; 149 sourceChannel.position(position); 150 } while (copied > 0 || position < sourceChannel.size()); 151 return position - oldPosition; 152 } 153 154 ByteBuffer buf = ByteBuffer.wrap(createBuffer()); 155 long total = 0; 156 while (from.read(buf) != -1) { 157 Java8Compatibility.flip(buf); 158 while (buf.hasRemaining()) { 159 total += to.write(buf); 160 } 161 Java8Compatibility.clear(buf); 162 } 163 return total; 164 } 165 166 /** Max array length on JVM. */ 167 private static final int MAX_ARRAY_LEN = Integer.MAX_VALUE - 8; 168 169 /** Large enough to never need to expand, given the geometric progression of buffer sizes. */ 170 private static final int TO_BYTE_ARRAY_DEQUE_SIZE = 20; 171 172 /** 173 * Returns a byte array containing the bytes from the buffers already in {@code bufs} (which have 174 * a total combined length of {@code totalLen} bytes) followed by all bytes remaining in the given 175 * input stream. 176 */ 177 private static byte[] toByteArrayInternal(InputStream in, Queue<byte[]> bufs, int totalLen) 178 throws IOException { 179 // Roughly size to match what has been read already. Some file systems, such as procfs, return 0 180 // as their length. These files are very small, so it's wasteful to allocate an 8KB buffer. 181 int initialBufferSize = min(BUFFER_SIZE, max(128, Integer.highestOneBit(totalLen) * 2)); 182 // Starting with an 8k buffer, double the size of each successive buffer. Smaller buffers 183 // quadruple in size until they reach 8k, to minimize the number of small reads for longer 184 // streams. Buffers are retained in a deque so that there's no copying between buffers while 185 // reading and so all of the bytes in each new allocated buffer are available for reading from 186 // the stream. 187 for (int bufSize = initialBufferSize; 188 totalLen < MAX_ARRAY_LEN; 189 bufSize = IntMath.saturatedMultiply(bufSize, bufSize < 4096 ? 4 : 2)) { 190 byte[] buf = new byte[min(bufSize, MAX_ARRAY_LEN - totalLen)]; 191 bufs.add(buf); 192 int off = 0; 193 while (off < buf.length) { 194 // always OK to fill buf; its size plus the rest of bufs is never more than MAX_ARRAY_LEN 195 int r = in.read(buf, off, buf.length - off); 196 if (r == -1) { 197 return combineBuffers(bufs, totalLen); 198 } 199 off += r; 200 totalLen += r; 201 } 202 } 203 204 // read MAX_ARRAY_LEN bytes without seeing end of stream 205 if (in.read() == -1) { 206 // oh, there's the end of the stream 207 return combineBuffers(bufs, MAX_ARRAY_LEN); 208 } else { 209 throw new OutOfMemoryError("input is too large to fit in a byte array"); 210 } 211 } 212 213 private static byte[] combineBuffers(Queue<byte[]> bufs, int totalLen) { 214 if (bufs.isEmpty()) { 215 return new byte[0]; 216 } 217 byte[] result = bufs.remove(); 218 if (result.length == totalLen) { 219 return result; 220 } 221 int remaining = totalLen - result.length; 222 result = Arrays.copyOf(result, totalLen); 223 while (remaining > 0) { 224 byte[] buf = bufs.remove(); 225 int bytesToCopy = min(remaining, buf.length); 226 int resultOffset = totalLen - remaining; 227 System.arraycopy(buf, 0, result, resultOffset, bytesToCopy); 228 remaining -= bytesToCopy; 229 } 230 return result; 231 } 232 233 /** 234 * Reads all bytes from an input stream into a byte array. Does not close the stream. 235 * 236 * <p><b>Java 9+ users:</b> use {@code in#readAllBytes()} instead. 237 * 238 * @param in the input stream to read from 239 * @return a byte array containing all the bytes from the stream 240 * @throws IOException if an I/O error occurs 241 */ 242 public static byte[] toByteArray(InputStream in) throws IOException { 243 checkNotNull(in); 244 return toByteArrayInternal(in, new ArrayDeque<byte[]>(TO_BYTE_ARRAY_DEQUE_SIZE), 0); 245 } 246 247 /** 248 * Reads all bytes from an input stream into a byte array. The given expected size is used to 249 * create an initial byte array, but if the actual number of bytes read from the stream differs, 250 * the correct result will be returned anyway. 251 */ 252 static byte[] toByteArray(InputStream in, long expectedSize) throws IOException { 253 checkArgument(expectedSize >= 0, "expectedSize (%s) must be non-negative", expectedSize); 254 if (expectedSize > MAX_ARRAY_LEN) { 255 throw new OutOfMemoryError(expectedSize + " bytes is too large to fit in a byte array"); 256 } 257 258 byte[] bytes = new byte[(int) expectedSize]; 259 int remaining = (int) expectedSize; 260 261 while (remaining > 0) { 262 int off = (int) expectedSize - remaining; 263 int read = in.read(bytes, off, remaining); 264 if (read == -1) { 265 // end of stream before reading expectedSize bytes 266 // just return the bytes read so far 267 return Arrays.copyOf(bytes, off); 268 } 269 remaining -= read; 270 } 271 272 // bytes is now full 273 int b = in.read(); 274 if (b == -1) { 275 return bytes; 276 } 277 278 // the stream was longer, so read the rest normally 279 Queue<byte[]> bufs = new ArrayDeque<>(TO_BYTE_ARRAY_DEQUE_SIZE + 2); 280 bufs.add(bytes); 281 bufs.add(new byte[] {(byte) b}); 282 return toByteArrayInternal(in, bufs, bytes.length + 1); 283 } 284 285 /** 286 * Reads and discards data from the given {@code InputStream} until the end of the stream is 287 * reached. Returns the total number of bytes read. Does not close the stream. 288 * 289 * @since 20.0 290 */ 291 @CanIgnoreReturnValue 292 public static long exhaust(InputStream in) throws IOException { 293 long total = 0; 294 long read; 295 byte[] buf = createBuffer(); 296 while ((read = in.read(buf)) != -1) { 297 total += read; 298 } 299 return total; 300 } 301 302 /** 303 * Returns a new {@link ByteArrayDataInput} instance to read from the {@code bytes} array from the 304 * beginning. 305 */ 306 public static ByteArrayDataInput newDataInput(byte[] bytes) { 307 return newDataInput(new ByteArrayInputStream(bytes)); 308 } 309 310 /** 311 * Returns a new {@link ByteArrayDataInput} instance to read from the {@code bytes} array, 312 * starting at the given position. 313 * 314 * @throws IndexOutOfBoundsException if {@code start} is negative or greater than the length of 315 * the array 316 */ 317 public static ByteArrayDataInput newDataInput(byte[] bytes, int start) { 318 checkPositionIndex(start, bytes.length); 319 return newDataInput(new ByteArrayInputStream(bytes, start, bytes.length - start)); 320 } 321 322 /** 323 * Returns a new {@link ByteArrayDataInput} instance to read from the given {@code 324 * ByteArrayInputStream}. The given input stream is not reset before being read from by the 325 * returned {@code ByteArrayDataInput}. 326 * 327 * @since 17.0 328 */ 329 public static ByteArrayDataInput newDataInput(ByteArrayInputStream byteArrayInputStream) { 330 return new ByteArrayDataInputStream(checkNotNull(byteArrayInputStream)); 331 } 332 333 private static class ByteArrayDataInputStream implements ByteArrayDataInput { 334 final DataInput input; 335 336 ByteArrayDataInputStream(ByteArrayInputStream byteArrayInputStream) { 337 this.input = new DataInputStream(byteArrayInputStream); 338 } 339 340 @Override 341 public void readFully(byte b[]) { 342 try { 343 input.readFully(b); 344 } catch (IOException e) { 345 throw new IllegalStateException(e); 346 } 347 } 348 349 @Override 350 public void readFully(byte b[], int off, int len) { 351 try { 352 input.readFully(b, off, len); 353 } catch (IOException e) { 354 throw new IllegalStateException(e); 355 } 356 } 357 358 @Override 359 public int skipBytes(int n) { 360 try { 361 return input.skipBytes(n); 362 } catch (IOException e) { 363 throw new IllegalStateException(e); 364 } 365 } 366 367 @Override 368 public boolean readBoolean() { 369 try { 370 return input.readBoolean(); 371 } catch (IOException e) { 372 throw new IllegalStateException(e); 373 } 374 } 375 376 @Override 377 public byte readByte() { 378 try { 379 return input.readByte(); 380 } catch (EOFException e) { 381 throw new IllegalStateException(e); 382 } catch (IOException impossible) { 383 throw new AssertionError(impossible); 384 } 385 } 386 387 @Override 388 public int readUnsignedByte() { 389 try { 390 return input.readUnsignedByte(); 391 } catch (IOException e) { 392 throw new IllegalStateException(e); 393 } 394 } 395 396 @Override 397 public short readShort() { 398 try { 399 return input.readShort(); 400 } catch (IOException e) { 401 throw new IllegalStateException(e); 402 } 403 } 404 405 @Override 406 public int readUnsignedShort() { 407 try { 408 return input.readUnsignedShort(); 409 } catch (IOException e) { 410 throw new IllegalStateException(e); 411 } 412 } 413 414 @Override 415 public char readChar() { 416 try { 417 return input.readChar(); 418 } catch (IOException e) { 419 throw new IllegalStateException(e); 420 } 421 } 422 423 @Override 424 public int readInt() { 425 try { 426 return input.readInt(); 427 } catch (IOException e) { 428 throw new IllegalStateException(e); 429 } 430 } 431 432 @Override 433 public long readLong() { 434 try { 435 return input.readLong(); 436 } catch (IOException e) { 437 throw new IllegalStateException(e); 438 } 439 } 440 441 @Override 442 public float readFloat() { 443 try { 444 return input.readFloat(); 445 } catch (IOException e) { 446 throw new IllegalStateException(e); 447 } 448 } 449 450 @Override 451 public double readDouble() { 452 try { 453 return input.readDouble(); 454 } catch (IOException e) { 455 throw new IllegalStateException(e); 456 } 457 } 458 459 @Override 460 @CheckForNull 461 public String readLine() { 462 try { 463 return input.readLine(); 464 } catch (IOException e) { 465 throw new IllegalStateException(e); 466 } 467 } 468 469 @Override 470 public String readUTF() { 471 try { 472 return input.readUTF(); 473 } catch (IOException e) { 474 throw new IllegalStateException(e); 475 } 476 } 477 } 478 479 /** Returns a new {@link ByteArrayDataOutput} instance with a default size. */ 480 public static ByteArrayDataOutput newDataOutput() { 481 return newDataOutput(new ByteArrayOutputStream()); 482 } 483 484 /** 485 * Returns a new {@link ByteArrayDataOutput} instance sized to hold {@code size} bytes before 486 * resizing. 487 * 488 * @throws IllegalArgumentException if {@code size} is negative 489 */ 490 public static ByteArrayDataOutput newDataOutput(int size) { 491 // When called at high frequency, boxing size generates too much garbage, 492 // so avoid doing that if we can. 493 if (size < 0) { 494 throw new IllegalArgumentException(String.format("Invalid size: %s", size)); 495 } 496 return newDataOutput(new ByteArrayOutputStream(size)); 497 } 498 499 /** 500 * Returns a new {@link ByteArrayDataOutput} instance which writes to the given {@code 501 * ByteArrayOutputStream}. The given output stream is not reset before being written to by the 502 * returned {@code ByteArrayDataOutput} and new data will be appended to any existing content. 503 * 504 * <p>Note that if the given output stream was not empty or is modified after the {@code 505 * ByteArrayDataOutput} is created, the contract for {@link ByteArrayDataOutput#toByteArray} will 506 * not be honored (the bytes returned in the byte array may not be exactly what was written via 507 * calls to {@code ByteArrayDataOutput}). 508 * 509 * @since 17.0 510 */ 511 public static ByteArrayDataOutput newDataOutput(ByteArrayOutputStream byteArrayOutputStream) { 512 return new ByteArrayDataOutputStream(checkNotNull(byteArrayOutputStream)); 513 } 514 515 private static class ByteArrayDataOutputStream implements ByteArrayDataOutput { 516 517 final DataOutput output; 518 final ByteArrayOutputStream byteArrayOutputStream; 519 520 ByteArrayDataOutputStream(ByteArrayOutputStream byteArrayOutputStream) { 521 this.byteArrayOutputStream = byteArrayOutputStream; 522 output = new DataOutputStream(byteArrayOutputStream); 523 } 524 525 @Override 526 public void write(int b) { 527 try { 528 output.write(b); 529 } catch (IOException impossible) { 530 throw new AssertionError(impossible); 531 } 532 } 533 534 @Override 535 public void write(byte[] b) { 536 try { 537 output.write(b); 538 } catch (IOException impossible) { 539 throw new AssertionError(impossible); 540 } 541 } 542 543 @Override 544 public void write(byte[] b, int off, int len) { 545 try { 546 output.write(b, off, len); 547 } catch (IOException impossible) { 548 throw new AssertionError(impossible); 549 } 550 } 551 552 @Override 553 public void writeBoolean(boolean v) { 554 try { 555 output.writeBoolean(v); 556 } catch (IOException impossible) { 557 throw new AssertionError(impossible); 558 } 559 } 560 561 @Override 562 public void writeByte(int v) { 563 try { 564 output.writeByte(v); 565 } catch (IOException impossible) { 566 throw new AssertionError(impossible); 567 } 568 } 569 570 @Override 571 public void writeBytes(String s) { 572 try { 573 output.writeBytes(s); 574 } catch (IOException impossible) { 575 throw new AssertionError(impossible); 576 } 577 } 578 579 @Override 580 public void writeChar(int v) { 581 try { 582 output.writeChar(v); 583 } catch (IOException impossible) { 584 throw new AssertionError(impossible); 585 } 586 } 587 588 @Override 589 public void writeChars(String s) { 590 try { 591 output.writeChars(s); 592 } catch (IOException impossible) { 593 throw new AssertionError(impossible); 594 } 595 } 596 597 @Override 598 public void writeDouble(double v) { 599 try { 600 output.writeDouble(v); 601 } catch (IOException impossible) { 602 throw new AssertionError(impossible); 603 } 604 } 605 606 @Override 607 public void writeFloat(float v) { 608 try { 609 output.writeFloat(v); 610 } catch (IOException impossible) { 611 throw new AssertionError(impossible); 612 } 613 } 614 615 @Override 616 public void writeInt(int v) { 617 try { 618 output.writeInt(v); 619 } catch (IOException impossible) { 620 throw new AssertionError(impossible); 621 } 622 } 623 624 @Override 625 public void writeLong(long v) { 626 try { 627 output.writeLong(v); 628 } catch (IOException impossible) { 629 throw new AssertionError(impossible); 630 } 631 } 632 633 @Override 634 public void writeShort(int v) { 635 try { 636 output.writeShort(v); 637 } catch (IOException impossible) { 638 throw new AssertionError(impossible); 639 } 640 } 641 642 @Override 643 public void writeUTF(String s) { 644 try { 645 output.writeUTF(s); 646 } catch (IOException impossible) { 647 throw new AssertionError(impossible); 648 } 649 } 650 651 @Override 652 public byte[] toByteArray() { 653 return byteArrayOutputStream.toByteArray(); 654 } 655 } 656 657 private static final OutputStream NULL_OUTPUT_STREAM = 658 new OutputStream() { 659 /** Discards the specified byte. */ 660 @Override 661 public void write(int b) {} 662 663 /** Discards the specified byte array. */ 664 @Override 665 public void write(byte[] b) { 666 checkNotNull(b); 667 } 668 669 /** Discards the specified byte array. */ 670 @Override 671 public void write(byte[] b, int off, int len) { 672 checkNotNull(b); 673 checkPositionIndexes(off, off + len, b.length); 674 } 675 676 @Override 677 public String toString() { 678 return "ByteStreams.nullOutputStream()"; 679 } 680 }; 681 682 /** 683 * Returns an {@link OutputStream} that simply discards written bytes. 684 * 685 * @since 14.0 (since 1.0 as com.google.common.io.NullOutputStream) 686 */ 687 public static OutputStream nullOutputStream() { 688 return NULL_OUTPUT_STREAM; 689 } 690 691 /** 692 * Wraps a {@link InputStream}, limiting the number of bytes which can be read. 693 * 694 * @param in the input stream to be wrapped 695 * @param limit the maximum number of bytes to be read 696 * @return a length-limited {@link InputStream} 697 * @since 14.0 (since 1.0 as com.google.common.io.LimitInputStream) 698 */ 699 public static InputStream limit(InputStream in, long limit) { 700 return new LimitedInputStream(in, limit); 701 } 702 703 private static final class LimitedInputStream extends FilterInputStream { 704 705 private long left; 706 private long mark = -1; 707 708 LimitedInputStream(InputStream in, long limit) { 709 super(in); 710 checkNotNull(in); 711 checkArgument(limit >= 0, "limit must be non-negative"); 712 left = limit; 713 } 714 715 @Override 716 public int available() throws IOException { 717 return (int) Math.min(in.available(), left); 718 } 719 720 // it's okay to mark even if mark isn't supported, as reset won't work 721 @Override 722 public synchronized void mark(int readLimit) { 723 in.mark(readLimit); 724 mark = left; 725 } 726 727 @Override 728 public int read() throws IOException { 729 if (left == 0) { 730 return -1; 731 } 732 733 int result = in.read(); 734 if (result != -1) { 735 --left; 736 } 737 return result; 738 } 739 740 @Override 741 public int read(byte[] b, int off, int len) throws IOException { 742 if (left == 0) { 743 return -1; 744 } 745 746 len = (int) Math.min(len, left); 747 int result = in.read(b, off, len); 748 if (result != -1) { 749 left -= result; 750 } 751 return result; 752 } 753 754 @Override 755 public synchronized void reset() throws IOException { 756 if (!in.markSupported()) { 757 throw new IOException("Mark not supported"); 758 } 759 if (mark == -1) { 760 throw new IOException("Mark not set"); 761 } 762 763 in.reset(); 764 left = mark; 765 } 766 767 @Override 768 public long skip(long n) throws IOException { 769 n = Math.min(n, left); 770 long skipped = in.skip(n); 771 left -= skipped; 772 return skipped; 773 } 774 } 775 776 /** 777 * Attempts to read enough bytes from the stream to fill the given byte array, with the same 778 * behavior as {@link DataInput#readFully(byte[])}. Does not close the stream. 779 * 780 * @param in the input stream to read from. 781 * @param b the buffer into which the data is read. 782 * @throws EOFException if this stream reaches the end before reading all the bytes. 783 * @throws IOException if an I/O error occurs. 784 */ 785 public static void readFully(InputStream in, byte[] b) throws IOException { 786 readFully(in, b, 0, b.length); 787 } 788 789 /** 790 * Attempts to read {@code len} bytes from the stream into the given array starting at {@code 791 * off}, with the same behavior as {@link DataInput#readFully(byte[], int, int)}. Does not close 792 * the stream. 793 * 794 * @param in the input stream to read from. 795 * @param b the buffer into which the data is read. 796 * @param off an int specifying the offset into the data. 797 * @param len an int specifying the number of bytes to read. 798 * @throws EOFException if this stream reaches the end before reading all the bytes. 799 * @throws IOException if an I/O error occurs. 800 */ 801 public static void readFully(InputStream in, byte[] b, int off, int len) throws IOException { 802 int read = read(in, b, off, len); 803 if (read != len) { 804 throw new EOFException( 805 "reached end of stream after reading " + read + " bytes; " + len + " bytes expected"); 806 } 807 } 808 809 /** 810 * Discards {@code n} bytes of data from the input stream. This method will block until the full 811 * amount has been skipped. Does not close the stream. 812 * 813 * @param in the input stream to read from 814 * @param n the number of bytes to skip 815 * @throws EOFException if this stream reaches the end before skipping all the bytes 816 * @throws IOException if an I/O error occurs, or the stream does not support skipping 817 */ 818 public static void skipFully(InputStream in, long n) throws IOException { 819 long skipped = skipUpTo(in, n); 820 if (skipped < n) { 821 throw new EOFException( 822 "reached end of stream after skipping " + skipped + " bytes; " + n + " bytes expected"); 823 } 824 } 825 826 /** 827 * Discards up to {@code n} bytes of data from the input stream. This method will block until 828 * either the full amount has been skipped or until the end of the stream is reached, whichever 829 * happens first. Returns the total number of bytes skipped. 830 */ 831 static long skipUpTo(InputStream in, long n) throws IOException { 832 long totalSkipped = 0; 833 // A buffer is allocated if skipSafely does not skip any bytes. 834 byte[] buf = null; 835 836 while (totalSkipped < n) { 837 long remaining = n - totalSkipped; 838 long skipped = skipSafely(in, remaining); 839 840 if (skipped == 0) { 841 // Do a buffered read since skipSafely could return 0 repeatedly, for example if 842 // in.available() always returns 0 (the default). 843 int skip = (int) Math.min(remaining, BUFFER_SIZE); 844 if (buf == null) { 845 // Allocate a buffer bounded by the maximum size that can be requested, for 846 // example an array of BUFFER_SIZE is unnecessary when the value of remaining 847 // is smaller. 848 buf = new byte[skip]; 849 } 850 if ((skipped = in.read(buf, 0, skip)) == -1) { 851 // Reached EOF 852 break; 853 } 854 } 855 856 totalSkipped += skipped; 857 } 858 859 return totalSkipped; 860 } 861 862 /** 863 * Attempts to skip up to {@code n} bytes from the given input stream, but not more than {@code 864 * in.available()} bytes. This prevents {@code FileInputStream} from skipping more bytes than 865 * actually remain in the file, something that it {@linkplain java.io.FileInputStream#skip(long) 866 * specifies} it can do in its Javadoc despite the fact that it is violating the contract of 867 * {@code InputStream.skip()}. 868 */ 869 private static long skipSafely(InputStream in, long n) throws IOException { 870 int available = in.available(); 871 return available == 0 ? 0 : in.skip(Math.min(available, n)); 872 } 873 874 /** 875 * Process the bytes of the given input stream using the given processor. 876 * 877 * @param input the input stream to process 878 * @param processor the object to which to pass the bytes of the stream 879 * @return the result of the byte processor 880 * @throws IOException if an I/O error occurs 881 * @since 14.0 882 */ 883 @CanIgnoreReturnValue // some processors won't return a useful result 884 @ParametricNullness 885 public static <T extends @Nullable Object> T readBytes( 886 InputStream input, ByteProcessor<T> processor) throws IOException { 887 checkNotNull(input); 888 checkNotNull(processor); 889 890 byte[] buf = createBuffer(); 891 int read; 892 do { 893 read = input.read(buf); 894 } while (read != -1 && processor.processBytes(buf, 0, read)); 895 return processor.getResult(); 896 } 897 898 /** 899 * Reads some bytes from an input stream and stores them into the buffer array {@code b}. This 900 * method blocks until {@code len} bytes of input data have been read into the array, or end of 901 * file is detected. The number of bytes read is returned, possibly zero. Does not close the 902 * stream. 903 * 904 * <p>A caller can detect EOF if the number of bytes read is less than {@code len}. All subsequent 905 * calls on the same stream will return zero. 906 * 907 * <p>If {@code b} is null, a {@code NullPointerException} is thrown. If {@code off} is negative, 908 * or {@code len} is negative, or {@code off+len} is greater than the length of the array {@code 909 * b}, then an {@code IndexOutOfBoundsException} is thrown. If {@code len} is zero, then no bytes 910 * are read. Otherwise, the first byte read is stored into element {@code b[off]}, the next one 911 * into {@code b[off+1]}, and so on. The number of bytes read is, at most, equal to {@code len}. 912 * 913 * @param in the input stream to read from 914 * @param b the buffer into which the data is read 915 * @param off an int specifying the offset into the data 916 * @param len an int specifying the number of bytes to read 917 * @return the number of bytes read 918 * @throws IOException if an I/O error occurs 919 * @throws IndexOutOfBoundsException if {@code off} is negative, if {@code len} is negative, or if 920 * {@code off + len} is greater than {@code b.length} 921 */ 922 @CanIgnoreReturnValue 923 // Sometimes you don't care how many bytes you actually read, I guess. 924 // (You know that it's either going to read len bytes or stop at EOF.) 925 public static int read(InputStream in, byte[] b, int off, int len) throws IOException { 926 checkNotNull(in); 927 checkNotNull(b); 928 if (len < 0) { 929 throw new IndexOutOfBoundsException(String.format("len (%s) cannot be negative", len)); 930 } 931 checkPositionIndexes(off, off + len, b.length); 932 int total = 0; 933 while (total < len) { 934 int result = in.read(b, off + total, len - total); 935 if (result == -1) { 936 break; 937 } 938 total += result; 939 } 940 return total; 941 } 942}