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; 023import static java.lang.System.arraycopy; 024import static java.util.Objects.requireNonNull; 025 026import com.google.common.annotations.GwtIncompatible; 027import com.google.common.annotations.J2ktIncompatible; 028import com.google.common.math.IntMath; 029import com.google.errorprone.annotations.CanIgnoreReturnValue; 030import com.google.errorprone.annotations.concurrent.GuardedBy; 031import java.io.ByteArrayInputStream; 032import java.io.ByteArrayOutputStream; 033import java.io.DataInput; 034import java.io.DataInputStream; 035import java.io.DataOutput; 036import java.io.DataOutputStream; 037import java.io.EOFException; 038import java.io.FilterInputStream; 039import java.io.IOException; 040import java.io.InputStream; 041import java.io.OutputStream; 042import java.nio.ByteBuffer; 043import java.nio.channels.FileChannel; 044import java.nio.channels.ReadableByteChannel; 045import java.nio.channels.WritableByteChannel; 046import java.util.ArrayDeque; 047import java.util.Arrays; 048import java.util.Queue; 049import org.jspecify.annotations.Nullable; 050 051/** 052 * Provides utility methods for working with byte arrays and I/O streams. 053 * 054 * @author Chris Nokleberg 055 * @author Colin Decker 056 * @since 1.0 057 */ 058@GwtIncompatible 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 @J2ktIncompatible 138 @CanIgnoreReturnValue 139 public static long copy(ReadableByteChannel from, WritableByteChannel to) throws IOException { 140 checkNotNull(from); 141 checkNotNull(to); 142 if (from instanceof FileChannel) { 143 FileChannel sourceChannel = (FileChannel) from; 144 long oldPosition = sourceChannel.position(); 145 long position = oldPosition; 146 long copied; 147 do { 148 copied = sourceChannel.transferTo(position, ZERO_COPY_CHUNK_SIZE, to); 149 position += copied; 150 sourceChannel.position(position); 151 } while (copied > 0 || position < sourceChannel.size()); 152 return position - oldPosition; 153 } 154 155 ByteBuffer buf = ByteBuffer.wrap(createBuffer()); 156 long total = 0; 157 while (from.read(buf) != -1) { 158 Java8Compatibility.flip(buf); 159 while (buf.hasRemaining()) { 160 total += to.write(buf); 161 } 162 Java8Compatibility.clear(buf); 163 } 164 return total; 165 } 166 167 /** Max array length on JVM. */ 168 private static final int MAX_ARRAY_LEN = Integer.MAX_VALUE - 8; 169 170 /** Large enough to never need to expand, given the geometric progression of buffer sizes. */ 171 private static final int TO_BYTE_ARRAY_DEQUE_SIZE = 20; 172 173 /** 174 * Returns a byte array containing the bytes from the buffers already in {@code bufs} (which have 175 * a total combined length of {@code totalLen} bytes) followed by all bytes remaining in the given 176 * input stream. 177 */ 178 private static byte[] toByteArrayInternal(InputStream in, Queue<byte[]> bufs, int totalLen) 179 throws IOException { 180 // Roughly size to match what has been read already. Some file systems, such as procfs, return 0 181 // as their length. These files are very small, so it's wasteful to allocate an 8KB buffer. 182 int initialBufferSize = min(BUFFER_SIZE, max(128, Integer.highestOneBit(totalLen) * 2)); 183 // Starting with an 8k buffer, double the size of each successive buffer. Smaller buffers 184 // quadruple in size until they reach 8k, to minimize the number of small reads for longer 185 // streams. Buffers are retained in a deque so that there's no copying between buffers while 186 // reading and so all of the bytes in each new allocated buffer are available for reading from 187 // the stream. 188 for (int bufSize = initialBufferSize; 189 totalLen < MAX_ARRAY_LEN; 190 bufSize = IntMath.saturatedMultiply(bufSize, bufSize < 4096 ? 4 : 2)) { 191 byte[] buf = new byte[min(bufSize, MAX_ARRAY_LEN - totalLen)]; 192 bufs.add(buf); 193 int off = 0; 194 while (off < buf.length) { 195 // always OK to fill buf; its size plus the rest of bufs is never more than MAX_ARRAY_LEN 196 int r = in.read(buf, off, buf.length - off); 197 if (r == -1) { 198 return combineBuffers(bufs, totalLen); 199 } 200 off += r; 201 totalLen += r; 202 } 203 } 204 205 // read MAX_ARRAY_LEN bytes without seeing end of stream 206 if (in.read() == -1) { 207 // oh, there's the end of the stream 208 return combineBuffers(bufs, MAX_ARRAY_LEN); 209 } else { 210 throw new OutOfMemoryError("input is too large to fit in a byte array"); 211 } 212 } 213 214 private static byte[] combineBuffers(Queue<byte[]> bufs, int totalLen) { 215 if (bufs.isEmpty()) { 216 return new byte[0]; 217 } 218 byte[] result = bufs.remove(); 219 if (result.length == totalLen) { 220 return result; 221 } 222 int remaining = totalLen - result.length; 223 result = Arrays.copyOf(result, totalLen); 224 while (remaining > 0) { 225 byte[] buf = bufs.remove(); 226 int bytesToCopy = min(remaining, buf.length); 227 int resultOffset = totalLen - remaining; 228 arraycopy(buf, 0, result, resultOffset, bytesToCopy); 229 remaining -= bytesToCopy; 230 } 231 return result; 232 } 233 234 /** 235 * Reads all bytes from an input stream into a byte array. Does not close the stream. 236 * 237 * <p><b>Java 9+ users:</b> use {@code in#readAllBytes()} instead. 238 * 239 * @param in the input stream to read from 240 * @return a byte array containing all the bytes from the stream 241 * @throws IOException if an I/O error occurs 242 */ 243 public static byte[] toByteArray(InputStream in) throws IOException { 244 checkNotNull(in); 245 return toByteArrayInternal(in, new ArrayDeque<byte[]>(TO_BYTE_ARRAY_DEQUE_SIZE), 0); 246 } 247 248 /** 249 * Reads all bytes from an input stream into a byte array. The given expected size is used to 250 * create an initial byte array, but if the actual number of bytes read from the stream differs, 251 * the correct result will be returned anyway. 252 */ 253 static byte[] toByteArray(InputStream in, long expectedSize) throws IOException { 254 checkArgument(expectedSize >= 0, "expectedSize (%s) must be non-negative", expectedSize); 255 if (expectedSize > MAX_ARRAY_LEN) { 256 throw new OutOfMemoryError(expectedSize + " bytes is too large to fit in a byte array"); 257 } 258 259 byte[] bytes = new byte[(int) expectedSize]; 260 int remaining = (int) expectedSize; 261 262 while (remaining > 0) { 263 int off = (int) expectedSize - remaining; 264 int read = in.read(bytes, off, remaining); 265 if (read == -1) { 266 // end of stream before reading expectedSize bytes 267 // just return the bytes read so far 268 return Arrays.copyOf(bytes, off); 269 } 270 remaining -= read; 271 } 272 273 // bytes is now full 274 int b = in.read(); 275 if (b == -1) { 276 return bytes; 277 } 278 279 // the stream was longer, so read the rest normally 280 Queue<byte[]> bufs = new ArrayDeque<>(TO_BYTE_ARRAY_DEQUE_SIZE + 2); 281 bufs.add(bytes); 282 bufs.add(new byte[] {(byte) b}); 283 return toByteArrayInternal(in, bufs, bytes.length + 1); 284 } 285 286 /** 287 * Reads and discards data from the given {@code InputStream} until the end of the stream is 288 * reached. Returns the total number of bytes read. Does not close the stream. 289 * 290 * @since 20.0 291 */ 292 @CanIgnoreReturnValue 293 public static long exhaust(InputStream in) throws IOException { 294 long total = 0; 295 long read; 296 byte[] buf = createBuffer(); 297 while ((read = in.read(buf)) != -1) { 298 total += read; 299 } 300 return total; 301 } 302 303 /** 304 * Returns a new {@link ByteArrayDataInput} instance to read from the {@code bytes} array from the 305 * beginning. 306 */ 307 @J2ktIncompatible 308 public static ByteArrayDataInput newDataInput(byte[] bytes) { 309 return newDataInput(new ByteArrayInputStream(bytes)); 310 } 311 312 /** 313 * Returns a new {@link ByteArrayDataInput} instance to read from the {@code bytes} array, 314 * starting at the given position. 315 * 316 * @throws IndexOutOfBoundsException if {@code start} is negative or greater than the length of 317 * the array 318 */ 319 @J2ktIncompatible 320 public static ByteArrayDataInput newDataInput(byte[] bytes, int start) { 321 checkPositionIndex(start, bytes.length); 322 return newDataInput(new ByteArrayInputStream(bytes, start, bytes.length - start)); 323 } 324 325 /** 326 * Returns a new {@link ByteArrayDataInput} instance to read from the given {@code 327 * ByteArrayInputStream}. The given input stream is not reset before being read from by the 328 * returned {@code ByteArrayDataInput}. 329 * 330 * @since 17.0 331 */ 332 @J2ktIncompatible 333 public static ByteArrayDataInput newDataInput(ByteArrayInputStream byteArrayInputStream) { 334 return new ByteArrayDataInputStream(checkNotNull(byteArrayInputStream)); 335 } 336 337 @J2ktIncompatible 338 private static final class ByteArrayDataInputStream implements ByteArrayDataInput { 339 final DataInput input; 340 341 ByteArrayDataInputStream(ByteArrayInputStream byteArrayInputStream) { 342 this.input = new DataInputStream(byteArrayInputStream); 343 } 344 345 @Override 346 public void readFully(byte[] b) { 347 try { 348 input.readFully(b); 349 } catch (IOException e) { 350 throw new IllegalStateException(e); 351 } 352 } 353 354 @Override 355 public void readFully(byte[] b, int off, int len) { 356 try { 357 input.readFully(b, off, len); 358 } catch (IOException e) { 359 throw new IllegalStateException(e); 360 } 361 } 362 363 @Override 364 public int skipBytes(int n) { 365 try { 366 return input.skipBytes(n); 367 } catch (IOException e) { 368 throw new IllegalStateException(e); 369 } 370 } 371 372 @Override 373 public boolean readBoolean() { 374 try { 375 return input.readBoolean(); 376 } catch (IOException e) { 377 throw new IllegalStateException(e); 378 } 379 } 380 381 @Override 382 public byte readByte() { 383 try { 384 return input.readByte(); 385 } catch (EOFException e) { 386 throw new IllegalStateException(e); 387 } catch (IOException impossible) { 388 throw new AssertionError(impossible); 389 } 390 } 391 392 @Override 393 public int readUnsignedByte() { 394 try { 395 return input.readUnsignedByte(); 396 } catch (IOException e) { 397 throw new IllegalStateException(e); 398 } 399 } 400 401 @Override 402 public short readShort() { 403 try { 404 return input.readShort(); 405 } catch (IOException e) { 406 throw new IllegalStateException(e); 407 } 408 } 409 410 @Override 411 public int readUnsignedShort() { 412 try { 413 return input.readUnsignedShort(); 414 } catch (IOException e) { 415 throw new IllegalStateException(e); 416 } 417 } 418 419 @Override 420 public char readChar() { 421 try { 422 return input.readChar(); 423 } catch (IOException e) { 424 throw new IllegalStateException(e); 425 } 426 } 427 428 @Override 429 public int readInt() { 430 try { 431 return input.readInt(); 432 } catch (IOException e) { 433 throw new IllegalStateException(e); 434 } 435 } 436 437 @Override 438 public long readLong() { 439 try { 440 return input.readLong(); 441 } catch (IOException e) { 442 throw new IllegalStateException(e); 443 } 444 } 445 446 @Override 447 public float readFloat() { 448 try { 449 return input.readFloat(); 450 } catch (IOException e) { 451 throw new IllegalStateException(e); 452 } 453 } 454 455 @Override 456 public double readDouble() { 457 try { 458 return input.readDouble(); 459 } catch (IOException e) { 460 throw new IllegalStateException(e); 461 } 462 } 463 464 @Override 465 public @Nullable String readLine() { 466 try { 467 return input.readLine(); 468 } catch (IOException e) { 469 throw new IllegalStateException(e); 470 } 471 } 472 473 @Override 474 public String readUTF() { 475 try { 476 return input.readUTF(); 477 } catch (IOException e) { 478 throw new IllegalStateException(e); 479 } 480 } 481 } 482 483 /** Returns a new {@link ByteArrayDataOutput} instance with a default size. */ 484 @J2ktIncompatible 485 public static ByteArrayDataOutput newDataOutput() { 486 return newDataOutput(new ByteArrayOutputStream()); 487 } 488 489 /** 490 * Returns a new {@link ByteArrayDataOutput} instance sized to hold {@code size} bytes before 491 * resizing. 492 * 493 * @throws IllegalArgumentException if {@code size} is negative 494 */ 495 @J2ktIncompatible 496 public static ByteArrayDataOutput newDataOutput(int size) { 497 // When called at high frequency, boxing size generates too much garbage, 498 // so avoid doing that if we can. 499 checkArgument(size >= 0, "Invalid size: %s", size); 500 return newDataOutput(new ByteArrayOutputStream(size)); 501 } 502 503 /** 504 * Returns a new {@link ByteArrayDataOutput} instance which writes to the given {@code 505 * ByteArrayOutputStream}. The given output stream is not reset before being written to by the 506 * returned {@code ByteArrayDataOutput} and new data will be appended to any existing content. 507 * 508 * <p>Note that if the given output stream was not empty or is modified after the {@code 509 * ByteArrayDataOutput} is created, the contract for {@link ByteArrayDataOutput#toByteArray} will 510 * not be honored (the bytes returned in the byte array may not be exactly what was written via 511 * calls to {@code ByteArrayDataOutput}). 512 * 513 * @since 17.0 514 */ 515 @J2ktIncompatible 516 public static ByteArrayDataOutput newDataOutput(ByteArrayOutputStream byteArrayOutputStream) { 517 return new ByteArrayDataOutputStream(checkNotNull(byteArrayOutputStream)); 518 } 519 520 @J2ktIncompatible 521 private static final class ByteArrayDataOutputStream implements ByteArrayDataOutput { 522 523 final DataOutput output; 524 final ByteArrayOutputStream byteArrayOutputStream; 525 526 ByteArrayDataOutputStream(ByteArrayOutputStream byteArrayOutputStream) { 527 this.byteArrayOutputStream = byteArrayOutputStream; 528 output = new DataOutputStream(byteArrayOutputStream); 529 } 530 531 @Override 532 public void write(int b) { 533 try { 534 output.write(b); 535 } catch (IOException impossible) { 536 throw new AssertionError(impossible); 537 } 538 } 539 540 @Override 541 public void write(byte[] b) { 542 try { 543 output.write(b); 544 } catch (IOException impossible) { 545 throw new AssertionError(impossible); 546 } 547 } 548 549 @Override 550 public void write(byte[] b, int off, int len) { 551 try { 552 output.write(b, off, len); 553 } catch (IOException impossible) { 554 throw new AssertionError(impossible); 555 } 556 } 557 558 @Override 559 public void writeBoolean(boolean v) { 560 try { 561 output.writeBoolean(v); 562 } catch (IOException impossible) { 563 throw new AssertionError(impossible); 564 } 565 } 566 567 @Override 568 public void writeByte(int v) { 569 try { 570 output.writeByte(v); 571 } catch (IOException impossible) { 572 throw new AssertionError(impossible); 573 } 574 } 575 576 @Override 577 public void writeBytes(String s) { 578 try { 579 output.writeBytes(s); 580 } catch (IOException impossible) { 581 throw new AssertionError(impossible); 582 } 583 } 584 585 @Override 586 public void writeChar(int v) { 587 try { 588 output.writeChar(v); 589 } catch (IOException impossible) { 590 throw new AssertionError(impossible); 591 } 592 } 593 594 @Override 595 public void writeChars(String s) { 596 try { 597 output.writeChars(s); 598 } catch (IOException impossible) { 599 throw new AssertionError(impossible); 600 } 601 } 602 603 @Override 604 public void writeDouble(double v) { 605 try { 606 output.writeDouble(v); 607 } catch (IOException impossible) { 608 throw new AssertionError(impossible); 609 } 610 } 611 612 @Override 613 public void writeFloat(float v) { 614 try { 615 output.writeFloat(v); 616 } catch (IOException impossible) { 617 throw new AssertionError(impossible); 618 } 619 } 620 621 @Override 622 public void writeInt(int v) { 623 try { 624 output.writeInt(v); 625 } catch (IOException impossible) { 626 throw new AssertionError(impossible); 627 } 628 } 629 630 @Override 631 public void writeLong(long v) { 632 try { 633 output.writeLong(v); 634 } catch (IOException impossible) { 635 throw new AssertionError(impossible); 636 } 637 } 638 639 @Override 640 public void writeShort(int v) { 641 try { 642 output.writeShort(v); 643 } catch (IOException impossible) { 644 throw new AssertionError(impossible); 645 } 646 } 647 648 @Override 649 public void writeUTF(String s) { 650 try { 651 output.writeUTF(s); 652 } catch (IOException impossible) { 653 throw new AssertionError(impossible); 654 } 655 } 656 657 @Override 658 public byte[] toByteArray() { 659 return byteArrayOutputStream.toByteArray(); 660 } 661 } 662 663 private static final OutputStream NULL_OUTPUT_STREAM = 664 new OutputStream() { 665 /** Discards the specified byte. */ 666 @Override 667 public void write(int b) {} 668 669 /** Discards the specified byte array. */ 670 @Override 671 public void write(byte[] b) { 672 checkNotNull(b); 673 } 674 675 /** Discards the specified byte array. */ 676 @Override 677 public void write(byte[] b, int off, int len) { 678 checkNotNull(b); 679 checkPositionIndexes(off, off + len, b.length); 680 } 681 682 @Override 683 public String toString() { 684 return "ByteStreams.nullOutputStream()"; 685 } 686 }; 687 688 /** 689 * Returns an {@link OutputStream} that simply discards written bytes. 690 * 691 * <p><b>Java 11+ users:</b> use {@link OutputStream#nullOutputStream()} instead. Note that the 692 * {@link ByteStreams} method returns a singleton stream whose {@code close} method has no effect, 693 * while the {@link OutputStream} method returns a new instance whose {@code write} methods throw 694 * if called on a closed stream. 695 * 696 * @since 14.0 (since 1.0 as com.google.common.io.NullOutputStream) 697 */ 698 public static OutputStream nullOutputStream() { 699 return NULL_OUTPUT_STREAM; 700 } 701 702 /** 703 * Wraps a {@link InputStream}, limiting the number of bytes which can be read. 704 * 705 * @param in the input stream to be wrapped 706 * @param limit the maximum number of bytes to be read 707 * @return a length-limited {@link InputStream} 708 * @since 14.0 (since 1.0 as com.google.common.io.LimitInputStream) 709 */ 710 @J2ktIncompatible 711 public static InputStream limit(InputStream in, long limit) { 712 return new LimitedInputStream(in, limit); 713 } 714 715 @J2ktIncompatible 716 private static final class LimitedInputStream extends FilterInputStream { 717 private long left; 718 719 @GuardedBy("this") 720 private long mark = -1; 721 722 LimitedInputStream(InputStream in, long limit) { 723 super(in); 724 checkNotNull(in); 725 checkArgument(limit >= 0, "limit must be non-negative"); 726 left = limit; 727 } 728 729 InputStream in() { 730 return requireNonNull(in); // guaranteed safe by the constructor 731 } 732 733 @Override 734 public int available() throws IOException { 735 return (int) min(in().available(), left); 736 } 737 738 // it's okay to mark even if mark isn't supported, as reset won't work 739 @Override 740 public synchronized void mark(int readLimit) { 741 in().mark(readLimit); 742 mark = left; 743 } 744 745 @Override 746 public int read() throws IOException { 747 if (left == 0) { 748 return -1; 749 } 750 751 int result = in().read(); 752 if (result != -1) { 753 --left; 754 } 755 return result; 756 } 757 758 @Override 759 public int read(byte[] b, int off, int len) throws IOException { 760 if (left == 0) { 761 return -1; 762 } 763 764 len = (int) min(len, left); 765 int result = in().read(b, off, len); 766 if (result != -1) { 767 left -= result; 768 } 769 return result; 770 } 771 772 @Override 773 public synchronized void reset() throws IOException { 774 if (!in().markSupported()) { 775 throw new IOException("Mark not supported"); 776 } 777 if (mark == -1) { 778 throw new IOException("Mark not set"); 779 } 780 781 in().reset(); 782 left = mark; 783 } 784 785 @Override 786 public long skip(long n) throws IOException { 787 n = min(n, left); 788 if (n <= 0) { 789 // Some streams, like FileInputStream, skip backward for a negative n. That would move 790 // before the position at which the limit began and increase the number of bytes left. 791 return 0; 792 } 793 long skipped = in().skip(n); 794 left -= skipped; 795 return skipped; 796 } 797 } 798 799 /** 800 * Attempts to read enough bytes from the stream to fill the given byte array, with the same 801 * behavior as {@link DataInput#readFully(byte[])}. Does not close the stream. 802 * 803 * @param in the input stream to read from. 804 * @param b the buffer into which the data is read. 805 * @throws EOFException if this stream reaches the end before reading all the bytes. 806 * @throws IOException if an I/O error occurs. 807 */ 808 public static void readFully(InputStream in, byte[] b) throws IOException { 809 readFully(in, b, 0, b.length); 810 } 811 812 /** 813 * Attempts to read {@code len} bytes from the stream into the given array starting at {@code 814 * off}, with the same behavior as {@link DataInput#readFully(byte[], int, int)}. Does not close 815 * the stream. 816 * 817 * @param in the input stream to read from. 818 * @param b the buffer into which the data is read. 819 * @param off an int specifying the offset into the data. 820 * @param len an int specifying the number of bytes to read. 821 * @throws EOFException if this stream reaches the end before reading all the bytes. 822 * @throws IOException if an I/O error occurs. 823 */ 824 public static void readFully(InputStream in, byte[] b, int off, int len) throws IOException { 825 int read = read(in, b, off, len); 826 if (read != len) { 827 throw new EOFException( 828 "reached end of stream after reading " + read + " bytes; " + len + " bytes expected"); 829 } 830 } 831 832 /** 833 * Discards {@code n} bytes of data from the input stream. This method will block until the full 834 * amount has been skipped. Does not close the stream. 835 * 836 * <p><b>Java 12+ users:</b> use {@link InputStream#skipNBytes} instead. 837 * 838 * @param in the input stream to read from 839 * @param n the number of bytes to skip. If {@code n} is zero or negative, then no bytes are 840 * skipped. 841 * @throws EOFException if this stream reaches the end before skipping all the bytes 842 * @throws IOException if an I/O error occurs, or the stream does not support skipping 843 */ 844 public static void skipFully(InputStream in, long n) throws IOException { 845 long skipped = skipUpTo(in, n); 846 if (skipped < n) { 847 throw new EOFException( 848 "reached end of stream after skipping " + skipped + " bytes; " + n + " bytes expected"); 849 } 850 } 851 852 /** 853 * Discards up to {@code n} bytes of data from the input stream. This method will block until 854 * either the full amount has been skipped or until the end of the stream is reached, whichever 855 * happens first. Returns the total number of bytes skipped. 856 */ 857 static long skipUpTo(InputStream in, long n) throws IOException { 858 long totalSkipped = 0; 859 // A buffer is allocated if skipSafely does not skip any bytes. 860 byte[] buf = null; 861 862 while (totalSkipped < n) { 863 long remaining = n - totalSkipped; 864 long skipped = skipSafely(in, remaining); 865 866 if (skipped == 0) { 867 // Do a buffered read since skipSafely could return 0 repeatedly, for example if 868 // in.available() always returns 0 (the default). 869 int skip = (int) min(remaining, BUFFER_SIZE); 870 if (buf == null) { 871 // Allocate a buffer bounded by the maximum size that can be requested, for 872 // example an array of BUFFER_SIZE is unnecessary when the value of remaining 873 // is smaller. 874 buf = new byte[skip]; 875 } 876 if ((skipped = in.read(buf, 0, skip)) == -1) { 877 // Reached EOF 878 break; 879 } 880 } 881 882 totalSkipped += skipped; 883 } 884 885 return totalSkipped; 886 } 887 888 /** 889 * Attempts to skip up to {@code n} bytes from the given input stream, but not more than {@code 890 * in.available()} bytes. This prevents {@code FileInputStream} from skipping more bytes than 891 * actually remain in the file, something that it {@linkplain java.io.FileInputStream#skip(long) 892 * specifies} it can do in its Javadoc despite the fact that it is violating the contract of 893 * {@code InputStream.skip()}. 894 */ 895 private static long skipSafely(InputStream in, long n) throws IOException { 896 int available = in.available(); 897 return available == 0 ? 0 : in.skip(min(available, n)); 898 } 899 900 /** 901 * Process the bytes of the given input stream using the given processor. 902 * 903 * @param input the input stream to process 904 * @param processor the object to which to pass the bytes of the stream 905 * @return the result of the byte processor 906 * @throws IOException if an I/O error occurs 907 * @since 14.0 908 */ 909 @CanIgnoreReturnValue // some processors won't return a useful result 910 @ParametricNullness 911 @J2ktIncompatible 912 public static <T extends @Nullable Object> T readBytes( 913 InputStream input, ByteProcessor<T> processor) throws IOException { 914 checkNotNull(input); 915 checkNotNull(processor); 916 917 byte[] buf = createBuffer(); 918 int read; 919 do { 920 read = input.read(buf); 921 } while (read != -1 && processor.processBytes(buf, 0, read)); 922 return processor.getResult(); 923 } 924 925 /** 926 * Reads some bytes from an input stream and stores them into the buffer array {@code b}. This 927 * method blocks until {@code len} bytes of input data have been read into the array, or end of 928 * file is detected. The number of bytes read is returned, possibly zero. Does not close the 929 * stream. 930 * 931 * <p>A caller can detect EOF if the number of bytes read is less than {@code len}. All subsequent 932 * calls on the same stream will return zero. 933 * 934 * <p>If {@code b} is null, a {@code NullPointerException} is thrown. If {@code off} is negative, 935 * or {@code len} is negative, or {@code off+len} is greater than the length of the array {@code 936 * b}, then an {@code IndexOutOfBoundsException} is thrown. If {@code len} is zero, then no bytes 937 * are read. Otherwise, the first byte read is stored into element {@code b[off]}, the next one 938 * into {@code b[off+1]}, and so on. The number of bytes read is, at most, equal to {@code len}. 939 * 940 * @param in the input stream to read from 941 * @param b the buffer into which the data is read 942 * @param off an int specifying the offset into the data 943 * @param len an int specifying the number of bytes to read 944 * @return the number of bytes read 945 * @throws IOException if an I/O error occurs 946 * @throws IndexOutOfBoundsException if {@code off} is negative, if {@code len} is negative, or if 947 * {@code off + len} is greater than {@code b.length} 948 */ 949 @CanIgnoreReturnValue 950 // Sometimes you don't care how many bytes you actually read, I guess. 951 // (You know that it's either going to read len bytes or stop at EOF.) 952 public static int read(InputStream in, byte[] b, int off, int len) throws IOException { 953 checkNotNull(in); 954 checkNotNull(b); 955 if (len < 0) { 956 throw new IndexOutOfBoundsException(String.format("len (%s) cannot be negative", len)); 957 } 958 checkPositionIndexes(off, off + len, b.length); 959 int total = 0; 960 while (total < len) { 961 int result = in.read(b, off + total, len - total); 962 if (result == -1) { 963 break; 964 } 965 total += result; 966 } 967 return total; 968 } 969 970 /** Compares the contents of the two {@link InputStream}s for equality. */ 971 static boolean contentsEqual(InputStream in1, InputStream in2) throws IOException { 972 byte[] buf1 = createBuffer(); 973 byte[] buf2 = createBuffer(); 974 while (true) { 975 int read1 = read(in1, buf1, 0, BUFFER_SIZE); 976 int read2 = read(in2, buf2, 0, BUFFER_SIZE); 977 if (read1 != read2 || !arraysEqual(buf1, buf2, read1)) { 978 return false; 979 } else if (read1 != BUFFER_SIZE) { 980 return true; 981 } 982 } 983 } 984 985 // The Arrays.equals(<arraytype>, int, int, <arraytype>, int, int) methods were not added until 986 // Java 9. This function is just returns the same result that 987 // Arrays.equals(array1, 0, count, array2, 0, count) would. It assumes that both arrays have a 988 // length of at least count. 989 private static boolean arraysEqual(byte[] array1, byte[] array2, int count) { 990 for (int i = 0; i < count; i++) { 991 if (array1[i] != array2[i]) { 992 return false; 993 } 994 } 995 return true; 996 } 997}