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; 021 022import com.google.common.annotations.Beta; 023import com.google.common.annotations.GwtIncompatible; 024import com.google.common.base.Function; 025import com.google.common.collect.Iterables; 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.Deque; 046 047/** 048 * Provides utility methods for working with byte arrays and I/O streams. 049 * 050 * @author Chris Nokleberg 051 * @author Colin Decker 052 * @since 1.0 053 */ 054@GwtIncompatible 055public final class ByteStreams { 056 057 private static final int BUFFER_SIZE = 8192; 058 059 /** Creates a new byte array for buffering reads or writes. */ 060 static byte[] createBuffer() { 061 return new byte[BUFFER_SIZE]; 062 } 063 064 /** 065 * There are three methods to implement {@link FileChannel#transferTo(long, long, 066 * WritableByteChannel)}: 067 * 068 * <ol> 069 * <li>Use sendfile(2) or equivalent. Requires that both the input channel and the output 070 * channel have their own file descriptors. Generally this only happens when both channels 071 * are files or sockets. This performs zero copies - the bytes never enter userspace. 072 * <li>Use mmap(2) or equivalent. Requires that either the input channel or the output channel 073 * have file descriptors. Bytes are copied from the file into a kernel buffer, then directly 074 * into the other buffer (userspace). Note that if the file is very large, a naive 075 * implementation will effectively put the whole file in memory. On many systems with paging 076 * and virtual memory, this is not a problem - because it is mapped read-only, the kernel 077 * can always page it to disk "for free". However, on systems where killing processes 078 * happens all the time in normal conditions (i.e., android) the OS must make a tradeoff 079 * between paging memory and killing other processes - so allocating a gigantic buffer and 080 * then sequentially accessing it could result in other processes dying. This is solvable 081 * via madvise(2), but that obviously doesn't exist in java. 082 * <li>Ordinary copy. Kernel copies bytes into a kernel buffer, from a kernel buffer into a 083 * userspace buffer (byte[] or ByteBuffer), then copies them from that buffer into the 084 * destination channel. 085 * </ol> 086 * 087 * This value is intended to be large enough to make the overhead of system calls negligible, 088 * without being so large that it causes problems for systems with atypical memory management if 089 * approaches 2 or 3 are used. 090 */ 091 private static final int ZERO_COPY_CHUNK_SIZE = 512 * 1024; 092 093 private ByteStreams() {} 094 095 /** 096 * Returns a factory that will supply instances of 097 * {@link ByteArrayInputStream} that read from the given byte array. 098 * 099 * @param b the input buffer 100 * @return the factory 101 * @deprecated Use {@link ByteSource#wrap(byte[])} instead. This method is 102 * scheduled for removal in Guava 18.0. 103 */ 104 @Deprecated 105 public static InputSupplier<ByteArrayInputStream> newInputStreamSupplier( 106 byte[] b) { 107 return asInputSupplier(ByteSource.wrap(b)); 108 } 109 110 /** 111 * Returns a factory that will supply instances of 112 * {@link ByteArrayInputStream} that read from the given byte array. 113 * 114 * @param b the input buffer 115 * @param off the offset in the buffer of the first byte to read 116 * @param len the maximum number of bytes to read from the buffer 117 * @return the factory 118 * @deprecated Use {@code ByteSource.wrap(b).slice(off, len)} instead. This 119 * method is scheduled for removal in Guava 18.0. 120 */ 121 @Deprecated 122 public static InputSupplier<ByteArrayInputStream> newInputStreamSupplier( 123 final byte[] b, final int off, final int len) { 124 return asInputSupplier(ByteSource.wrap(b).slice(off, len)); 125 } 126 127 /** 128 * Copies all bytes from the input stream to the output stream. Does not close or flush either 129 * stream. 130 * 131 * @param from the input stream to read from 132 * @param to the output stream to write to 133 * @return the number of bytes copied 134 * @throws IOException if an I/O error occurs 135 */ 136 @CanIgnoreReturnValue 137 public static long copy(InputStream from, OutputStream to) throws IOException { 138 checkNotNull(from); 139 checkNotNull(to); 140 byte[] buf = createBuffer(); 141 long total = 0; 142 while (true) { 143 int r = from.read(buf); 144 if (r == -1) { 145 break; 146 } 147 to.write(buf, 0, r); 148 total += r; 149 } 150 return total; 151 } 152 153 /** 154 * Copies all bytes from the readable channel to the writable channel. Does not close or flush 155 * either channel. 156 * 157 * @param from the readable channel to read from 158 * @param to the writable channel to write to 159 * @return the number of bytes copied 160 * @throws IOException if an I/O error occurs 161 */ 162 @CanIgnoreReturnValue 163 public static long copy(ReadableByteChannel from, WritableByteChannel to) throws IOException { 164 checkNotNull(from); 165 checkNotNull(to); 166 if (from instanceof FileChannel) { 167 FileChannel sourceChannel = (FileChannel) from; 168 long oldPosition = sourceChannel.position(); 169 long position = oldPosition; 170 long copied; 171 do { 172 copied = sourceChannel.transferTo(position, ZERO_COPY_CHUNK_SIZE, to); 173 position += copied; 174 sourceChannel.position(position); 175 } while (copied > 0 || position < sourceChannel.size()); 176 return position - oldPosition; 177 } 178 179 ByteBuffer buf = ByteBuffer.wrap(createBuffer()); 180 long total = 0; 181 while (from.read(buf) != -1) { 182 buf.flip(); 183 while (buf.hasRemaining()) { 184 total += to.write(buf); 185 } 186 buf.clear(); 187 } 188 return total; 189 } 190 191 /** Max array length on JVM. */ 192 private static final int MAX_ARRAY_LEN = Integer.MAX_VALUE - 8; 193 194 /** Large enough to never need to expand, given the geometric progression of buffer sizes. */ 195 private static final int TO_BYTE_ARRAY_DEQUE_SIZE = 20; 196 197 /** 198 * Returns a byte array containing the bytes from the buffers already in {@code bufs} (which have 199 * a total combined length of {@code totalLen} bytes) followed by all bytes remaining in the given 200 * input stream. 201 */ 202 private static byte[] toByteArrayInternal(InputStream in, Deque<byte[]> bufs, int totalLen) 203 throws IOException { 204 // Starting with an 8k buffer, double the size of each sucessive buffer. Buffers are retained 205 // in a deque so that there's no copying between buffers while reading and so all of the bytes 206 // in each new allocated buffer are available for reading from the stream. 207 for (int bufSize = BUFFER_SIZE; 208 totalLen < MAX_ARRAY_LEN; 209 bufSize = IntMath.saturatedMultiply(bufSize, 2)) { 210 byte[] buf = new byte[Math.min(bufSize, MAX_ARRAY_LEN - totalLen)]; 211 bufs.add(buf); 212 int off = 0; 213 while (off < buf.length) { 214 // always OK to fill buf; its size plus the rest of bufs is never more than MAX_ARRAY_LEN 215 int r = in.read(buf, off, buf.length - off); 216 if (r == -1) { 217 return combineBuffers(bufs, totalLen); 218 } 219 off += r; 220 totalLen += r; 221 } 222 } 223 224 // read MAX_ARRAY_LEN bytes without seeing end of stream 225 if (in.read() == -1) { 226 // oh, there's the end of the stream 227 return combineBuffers(bufs, MAX_ARRAY_LEN); 228 } else { 229 throw new OutOfMemoryError("input is too large to fit in a byte array"); 230 } 231 } 232 233 private static byte[] combineBuffers(Deque<byte[]> bufs, int totalLen) { 234 byte[] result = new byte[totalLen]; 235 int remaining = totalLen; 236 while (remaining > 0) { 237 byte[] buf = bufs.removeFirst(); 238 int bytesToCopy = Math.min(remaining, buf.length); 239 int resultOffset = totalLen - remaining; 240 System.arraycopy(buf, 0, result, resultOffset, bytesToCopy); 241 remaining -= bytesToCopy; 242 } 243 return result; 244 } 245 246 /** 247 * Reads all bytes from an input stream into a byte array. Does not close the stream. 248 * 249 * @param in the input stream to read from 250 * @return a byte array containing all the bytes from the stream 251 * @throws IOException if an I/O error occurs 252 */ 253 public static byte[] toByteArray(InputStream in) throws IOException { 254 checkNotNull(in); 255 return toByteArrayInternal(in, new ArrayDeque<byte[]>(TO_BYTE_ARRAY_DEQUE_SIZE), 0); 256 } 257 258 /** 259 * Reads all bytes from an input stream into a byte array. The given expected size is used to 260 * create an initial byte array, but if the actual number of bytes read from the stream differs, 261 * the correct result will be returned anyway. 262 */ 263 static byte[] toByteArray(InputStream in, long expectedSize) throws IOException { 264 checkArgument(expectedSize >= 0, "expectedSize (%s) must be non-negative", expectedSize); 265 if (expectedSize > MAX_ARRAY_LEN) { 266 throw new OutOfMemoryError(expectedSize + " bytes is too large to fit in a byte array"); 267 } 268 269 byte[] bytes = new byte[(int) expectedSize]; 270 int remaining = (int) expectedSize; 271 272 while (remaining > 0) { 273 int off = (int) expectedSize - remaining; 274 int read = in.read(bytes, off, remaining); 275 if (read == -1) { 276 // end of stream before reading expectedSize bytes 277 // just return the bytes read so far 278 return Arrays.copyOf(bytes, off); 279 } 280 remaining -= read; 281 } 282 283 // bytes is now full 284 int b = in.read(); 285 if (b == -1) { 286 return bytes; 287 } 288 289 // the stream was longer, so read the rest normally 290 Deque<byte[]> bufs = new ArrayDeque<byte[]>(TO_BYTE_ARRAY_DEQUE_SIZE + 2); 291 bufs.add(bytes); 292 bufs.add(new byte[] {(byte) b}); 293 return toByteArrayInternal(in, bufs, bytes.length + 1); 294 } 295 296 /** 297 * Reads and discards data from the given {@code InputStream} until the end of the stream is 298 * reached. Returns the total number of bytes read. Does not close the stream. 299 * 300 * @since 20.0 301 */ 302 @CanIgnoreReturnValue 303 @Beta 304 public static long exhaust(InputStream in) throws IOException { 305 long total = 0; 306 long read; 307 byte[] buf = createBuffer(); 308 while ((read = in.read(buf)) != -1) { 309 total += read; 310 } 311 return total; 312 } 313 314 /** 315 * Returns a new {@link ByteArrayDataInput} instance to read from the {@code bytes} array from the 316 * beginning. 317 */ 318 @Beta 319 public static ByteArrayDataInput newDataInput(byte[] bytes) { 320 return newDataInput(new ByteArrayInputStream(bytes)); 321 } 322 323 /** 324 * Returns a new {@link ByteArrayDataInput} instance to read from the {@code bytes} array, 325 * starting at the given position. 326 * 327 * @throws IndexOutOfBoundsException if {@code start} is negative or greater than the length of 328 * the array 329 */ 330 @Beta 331 public static ByteArrayDataInput newDataInput(byte[] bytes, int start) { 332 checkPositionIndex(start, bytes.length); 333 return newDataInput(new ByteArrayInputStream(bytes, start, bytes.length - start)); 334 } 335 336 /** 337 * Returns a new {@link ByteArrayDataInput} instance to read from the given {@code 338 * ByteArrayInputStream}. The given input stream is not reset before being read from by the 339 * returned {@code ByteArrayDataInput}. 340 * 341 * @since 17.0 342 */ 343 @Beta 344 public static ByteArrayDataInput newDataInput(ByteArrayInputStream byteArrayInputStream) { 345 return new ByteArrayDataInputStream(checkNotNull(byteArrayInputStream)); 346 } 347 348 private static class ByteArrayDataInputStream implements ByteArrayDataInput { 349 final DataInput input; 350 351 ByteArrayDataInputStream(ByteArrayInputStream byteArrayInputStream) { 352 this.input = new DataInputStream(byteArrayInputStream); 353 } 354 355 @Override 356 public void readFully(byte b[]) { 357 try { 358 input.readFully(b); 359 } catch (IOException e) { 360 throw new IllegalStateException(e); 361 } 362 } 363 364 @Override 365 public void readFully(byte b[], int off, int len) { 366 try { 367 input.readFully(b, off, len); 368 } catch (IOException e) { 369 throw new IllegalStateException(e); 370 } 371 } 372 373 @Override 374 public int skipBytes(int n) { 375 try { 376 return input.skipBytes(n); 377 } catch (IOException e) { 378 throw new IllegalStateException(e); 379 } 380 } 381 382 @Override 383 public boolean readBoolean() { 384 try { 385 return input.readBoolean(); 386 } catch (IOException e) { 387 throw new IllegalStateException(e); 388 } 389 } 390 391 @Override 392 public byte readByte() { 393 try { 394 return input.readByte(); 395 } catch (EOFException e) { 396 throw new IllegalStateException(e); 397 } catch (IOException impossible) { 398 throw new AssertionError(impossible); 399 } 400 } 401 402 @Override 403 public int readUnsignedByte() { 404 try { 405 return input.readUnsignedByte(); 406 } catch (IOException e) { 407 throw new IllegalStateException(e); 408 } 409 } 410 411 @Override 412 public short readShort() { 413 try { 414 return input.readShort(); 415 } catch (IOException e) { 416 throw new IllegalStateException(e); 417 } 418 } 419 420 @Override 421 public int readUnsignedShort() { 422 try { 423 return input.readUnsignedShort(); 424 } catch (IOException e) { 425 throw new IllegalStateException(e); 426 } 427 } 428 429 @Override 430 public char readChar() { 431 try { 432 return input.readChar(); 433 } catch (IOException e) { 434 throw new IllegalStateException(e); 435 } 436 } 437 438 @Override 439 public int readInt() { 440 try { 441 return input.readInt(); 442 } catch (IOException e) { 443 throw new IllegalStateException(e); 444 } 445 } 446 447 @Override 448 public long readLong() { 449 try { 450 return input.readLong(); 451 } catch (IOException e) { 452 throw new IllegalStateException(e); 453 } 454 } 455 456 @Override 457 public float readFloat() { 458 try { 459 return input.readFloat(); 460 } catch (IOException e) { 461 throw new IllegalStateException(e); 462 } 463 } 464 465 @Override 466 public double readDouble() { 467 try { 468 return input.readDouble(); 469 } catch (IOException e) { 470 throw new IllegalStateException(e); 471 } 472 } 473 474 @Override 475 public String readLine() { 476 try { 477 return input.readLine(); 478 } catch (IOException e) { 479 throw new IllegalStateException(e); 480 } 481 } 482 483 @Override 484 public String readUTF() { 485 try { 486 return input.readUTF(); 487 } catch (IOException e) { 488 throw new IllegalStateException(e); 489 } 490 } 491 } 492 493 /** Returns a new {@link ByteArrayDataOutput} instance with a default size. */ 494 @Beta 495 public static ByteArrayDataOutput newDataOutput() { 496 return newDataOutput(new ByteArrayOutputStream()); 497 } 498 499 /** 500 * Returns a new {@link ByteArrayDataOutput} instance sized to hold {@code size} bytes before 501 * resizing. 502 * 503 * @throws IllegalArgumentException if {@code size} is negative 504 */ 505 @Beta 506 public static ByteArrayDataOutput newDataOutput(int size) { 507 // When called at high frequency, boxing size generates too much garbage, 508 // so avoid doing that if we can. 509 if (size < 0) { 510 throw new IllegalArgumentException(String.format("Invalid size: %s", size)); 511 } 512 return newDataOutput(new ByteArrayOutputStream(size)); 513 } 514 515 /** 516 * Returns a new {@link ByteArrayDataOutput} instance which writes to the given {@code 517 * ByteArrayOutputStream}. The given output stream is not reset before being written to by the 518 * returned {@code ByteArrayDataOutput} and new data will be appended to any existing content. 519 * 520 * <p>Note that if the given output stream was not empty or is modified after the {@code 521 * ByteArrayDataOutput} is created, the contract for {@link ByteArrayDataOutput#toByteArray} will 522 * not be honored (the bytes returned in the byte array may not be exactly what was written via 523 * calls to {@code ByteArrayDataOutput}). 524 * 525 * @since 17.0 526 */ 527 @Beta 528 public static ByteArrayDataOutput newDataOutput(ByteArrayOutputStream byteArrayOutputStream) { 529 return new ByteArrayDataOutputStream(checkNotNull(byteArrayOutputStream)); 530 } 531 532 private static class ByteArrayDataOutputStream implements ByteArrayDataOutput { 533 534 final DataOutput output; 535 final ByteArrayOutputStream byteArrayOutputStream; 536 537 ByteArrayDataOutputStream(ByteArrayOutputStream byteArrayOutputStream) { 538 this.byteArrayOutputStream = byteArrayOutputStream; 539 output = new DataOutputStream(byteArrayOutputStream); 540 } 541 542 @Override 543 public void write(int b) { 544 try { 545 output.write(b); 546 } catch (IOException impossible) { 547 throw new AssertionError(impossible); 548 } 549 } 550 551 @Override 552 public void write(byte[] b) { 553 try { 554 output.write(b); 555 } catch (IOException impossible) { 556 throw new AssertionError(impossible); 557 } 558 } 559 560 @Override 561 public void write(byte[] b, int off, int len) { 562 try { 563 output.write(b, off, len); 564 } catch (IOException impossible) { 565 throw new AssertionError(impossible); 566 } 567 } 568 569 @Override 570 public void writeBoolean(boolean v) { 571 try { 572 output.writeBoolean(v); 573 } catch (IOException impossible) { 574 throw new AssertionError(impossible); 575 } 576 } 577 578 @Override 579 public void writeByte(int v) { 580 try { 581 output.writeByte(v); 582 } catch (IOException impossible) { 583 throw new AssertionError(impossible); 584 } 585 } 586 587 @Override 588 public void writeBytes(String s) { 589 try { 590 output.writeBytes(s); 591 } catch (IOException impossible) { 592 throw new AssertionError(impossible); 593 } 594 } 595 596 @Override 597 public void writeChar(int v) { 598 try { 599 output.writeChar(v); 600 } catch (IOException impossible) { 601 throw new AssertionError(impossible); 602 } 603 } 604 605 @Override 606 public void writeChars(String s) { 607 try { 608 output.writeChars(s); 609 } catch (IOException impossible) { 610 throw new AssertionError(impossible); 611 } 612 } 613 614 @Override 615 public void writeDouble(double v) { 616 try { 617 output.writeDouble(v); 618 } catch (IOException impossible) { 619 throw new AssertionError(impossible); 620 } 621 } 622 623 @Override 624 public void writeFloat(float v) { 625 try { 626 output.writeFloat(v); 627 } catch (IOException impossible) { 628 throw new AssertionError(impossible); 629 } 630 } 631 632 @Override 633 public void writeInt(int v) { 634 try { 635 output.writeInt(v); 636 } catch (IOException impossible) { 637 throw new AssertionError(impossible); 638 } 639 } 640 641 @Override 642 public void writeLong(long v) { 643 try { 644 output.writeLong(v); 645 } catch (IOException impossible) { 646 throw new AssertionError(impossible); 647 } 648 } 649 650 @Override 651 public void writeShort(int v) { 652 try { 653 output.writeShort(v); 654 } catch (IOException impossible) { 655 throw new AssertionError(impossible); 656 } 657 } 658 659 @Override 660 public void writeUTF(String s) { 661 try { 662 output.writeUTF(s); 663 } catch (IOException impossible) { 664 throw new AssertionError(impossible); 665 } 666 } 667 668 @Override 669 public byte[] toByteArray() { 670 return byteArrayOutputStream.toByteArray(); 671 } 672 } 673 674 private static final OutputStream NULL_OUTPUT_STREAM = 675 new OutputStream() { 676 /** Discards the specified byte. */ 677 @Override 678 public void write(int b) {} 679 680 /** Discards the specified byte array. */ 681 @Override 682 public void write(byte[] b) { 683 checkNotNull(b); 684 } 685 686 /** Discards the specified byte array. */ 687 @Override 688 public void write(byte[] b, int off, int len) { 689 checkNotNull(b); 690 } 691 692 @Override 693 public String toString() { 694 return "ByteStreams.nullOutputStream()"; 695 } 696 }; 697 698 /** 699 * Returns an {@link OutputStream} that simply discards written bytes. 700 * 701 * @since 14.0 (since 1.0 as com.google.common.io.NullOutputStream) 702 */ 703 @Beta 704 public static OutputStream nullOutputStream() { 705 return NULL_OUTPUT_STREAM; 706 } 707 708 /** 709 * Wraps a {@link InputStream}, limiting the number of bytes which can be read. 710 * 711 * @param in the input stream to be wrapped 712 * @param limit the maximum number of bytes to be read 713 * @return a length-limited {@link InputStream} 714 * @since 14.0 (since 1.0 as com.google.common.io.LimitInputStream) 715 */ 716 @Beta 717 public static InputStream limit(InputStream in, long limit) { 718 return new LimitedInputStream(in, limit); 719 } 720 721 private static final class LimitedInputStream extends FilterInputStream { 722 723 private long left; 724 private long mark = -1; 725 726 LimitedInputStream(InputStream in, long limit) { 727 super(in); 728 checkNotNull(in); 729 checkArgument(limit >= 0, "limit must be non-negative"); 730 left = limit; 731 } 732 733 @Override 734 public int available() throws IOException { 735 return (int) Math.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) Math.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 = Math.min(n, left); 788 long skipped = in.skip(n); 789 left -= skipped; 790 return skipped; 791 } 792 } 793 794 /** 795 * Attempts to read enough bytes from the stream to fill the given byte array, with the same 796 * behavior as {@link DataInput#readFully(byte[])}. Does not close the stream. 797 * 798 * @param in the input stream to read from. 799 * @param b the buffer into which the data is read. 800 * @throws EOFException if this stream reaches the end before reading all the bytes. 801 * @throws IOException if an I/O error occurs. 802 */ 803 @Beta 804 public static void readFully(InputStream in, byte[] b) throws IOException { 805 readFully(in, b, 0, b.length); 806 } 807 808 /** 809 * Attempts to read {@code len} bytes from the stream into the given array starting at {@code 810 * off}, with the same behavior as {@link DataInput#readFully(byte[], int, int)}. Does not close 811 * the stream. 812 * 813 * @param in the input stream to read from. 814 * @param b the buffer into which the data is read. 815 * @param off an int specifying the offset into the data. 816 * @param len an int specifying the number of bytes to read. 817 * @throws EOFException if this stream reaches the end before reading all the bytes. 818 * @throws IOException if an I/O error occurs. 819 */ 820 @Beta 821 public static void readFully(InputStream in, byte[] b, int off, int len) throws IOException { 822 int read = read(in, b, off, len); 823 if (read != len) { 824 throw new EOFException( 825 "reached end of stream after reading " + read + " bytes; " + len + " bytes expected"); 826 } 827 } 828 829 /** 830 * Discards {@code n} bytes of data from the input stream. This method will block until the full 831 * amount has been skipped. Does not close the stream. 832 * 833 * @param in the input stream to read from 834 * @param n the number of bytes to skip 835 * @throws EOFException if this stream reaches the end before skipping all the bytes 836 * @throws IOException if an I/O error occurs, or the stream does not support skipping 837 */ 838 @Beta 839 public static void skipFully(InputStream in, long n) throws IOException { 840 long skipped = skipUpTo(in, n); 841 if (skipped < n) { 842 throw new EOFException( 843 "reached end of stream after skipping " + skipped + " bytes; " + n + " bytes expected"); 844 } 845 } 846 847 /** 848 * Discards up to {@code n} bytes of data from the input stream. This method will block until 849 * either the full amount has been skipped or until the end of the stream is reached, whichever 850 * happens first. Returns the total number of bytes skipped. 851 */ 852 static long skipUpTo(InputStream in, final long n) throws IOException { 853 long totalSkipped = 0; 854 // A buffer is allocated if skipSafely does not skip any bytes. 855 byte[] buf = null; 856 857 while (totalSkipped < n) { 858 long remaining = n - totalSkipped; 859 long skipped = skipSafely(in, remaining); 860 861 if (skipped == 0) { 862 // Do a buffered read since skipSafely could return 0 repeatedly, for example if 863 // in.available() always returns 0 (the default). 864 int skip = (int) Math.min(remaining, BUFFER_SIZE); 865 if (buf == null) { 866 // Allocate a buffer bounded by the maximum size that can be requested, for 867 // example an array of BUFFER_SIZE is unnecessary when the value of remaining 868 // is smaller. 869 buf = new byte[skip]; 870 } 871 if ((skipped = in.read(buf, 0, skip)) == -1) { 872 // Reached EOF 873 break; 874 } 875 } 876 877 totalSkipped += skipped; 878 } 879 880 return totalSkipped; 881 } 882 883 /** 884 * Attempts to skip up to {@code n} bytes from the given input stream, but not more than {@code 885 * in.available()} bytes. This prevents {@code FileInputStream} from skipping more bytes than 886 * actually remain in the file, something that it {@linkplain java.io.FileInputStream#skip(long) 887 * specifies} it can do in its Javadoc despite the fact that it is violating the contract of 888 * {@code InputStream.skip()}. 889 */ 890 private static long skipSafely(InputStream in, long n) throws IOException { 891 int available = in.available(); 892 return available == 0 ? 0 : in.skip(Math.min(available, n)); 893 } 894 895 /** 896 * Process the bytes of the given input stream using the given processor. 897 * 898 * @param input the input stream to process 899 * @param processor the object to which to pass the bytes of the stream 900 * @return the result of the byte processor 901 * @throws IOException if an I/O error occurs 902 * @since 14.0 903 */ 904 @Beta 905 @CanIgnoreReturnValue // some processors won't return a useful result 906 public static <T> T readBytes(InputStream input, ByteProcessor<T> processor) throws IOException { 907 checkNotNull(input); 908 checkNotNull(processor); 909 910 byte[] buf = createBuffer(); 911 int read; 912 do { 913 read = input.read(buf); 914 } while (read != -1 && processor.processBytes(buf, 0, read)); 915 return processor.getResult(); 916 } 917 918 /** 919 * Reads some bytes from an input stream and stores them into the buffer array {@code b}. This 920 * method blocks until {@code len} bytes of input data have been read into the array, or end of 921 * file is detected. The number of bytes read is returned, possibly zero. Does not close the 922 * stream. 923 * 924 * <p>A caller can detect EOF if the number of bytes read is less than {@code len}. All subsequent 925 * calls on the same stream will return zero. 926 * 927 * <p>If {@code b} is null, a {@code NullPointerException} is thrown. If {@code off} is negative, 928 * or {@code len} is negative, or {@code off+len} is greater than the length of the array {@code 929 * b}, then an {@code IndexOutOfBoundsException} is thrown. If {@code len} is zero, then no bytes 930 * are read. Otherwise, the first byte read is stored into element {@code b[off]}, the next one 931 * into {@code b[off+1]}, and so on. The number of bytes read is, at most, equal to {@code len}. 932 * 933 * @param in the input stream to read from 934 * @param b the buffer into which the data is read 935 * @param off an int specifying the offset into the data 936 * @param len an int specifying the number of bytes to read 937 * @return the number of bytes read 938 * @throws IOException if an I/O error occurs 939 * @throws IndexOutOfBoundsException if {@code off} is negative, if {@code len} is negative, or if 940 * {@code off + len} is greater than {@code b.length} 941 */ 942 @Beta 943 @CanIgnoreReturnValue 944 // Sometimes you don't care how many bytes you actually read, I guess. 945 // (You know that it's either going to read len bytes or stop at EOF.) 946 public static int read(InputStream in, byte[] b, int off, int len) throws IOException { 947 checkNotNull(in); 948 checkNotNull(b); 949 if (len < 0) { 950 throw new IndexOutOfBoundsException(String.format("len (%s) cannot be negative", len)); 951 } 952 checkPositionIndexes(off, off + len, b.length); 953 int total = 0; 954 while (total < len) { 955 int result = in.read(b, off + total, len - total); 956 if (result == -1) { 957 break; 958 } 959 total += result; 960 } 961 return total; 962 } 963 964 /** 965 * Returns an {@link InputSupplier} that returns input streams from the 966 * an underlying supplier, where each stream starts at the given 967 * offset and is limited to the specified number of bytes. 968 * 969 * @param supplier the supplier from which to get the raw streams 970 * @param offset the offset in bytes into the underlying stream where 971 * the returned streams will start 972 * @param length the maximum length of the returned streams 973 * @throws IllegalArgumentException if offset or length are negative 974 * @deprecated Use {@link ByteSource#slice(int, int)} instead. This method is 975 * scheduled for removal in Guava 18.0. 976 */ 977 @Deprecated 978 public static InputSupplier<InputStream> slice( 979 final InputSupplier<? extends InputStream> supplier, 980 final long offset, 981 final long length) { 982 return asInputSupplier(asByteSource(supplier).slice(offset, length)); 983 } 984 985 /** 986 * Joins multiple {@link InputStream} suppliers into a single supplier. 987 * Streams returned from the supplier will contain the concatenated data from 988 * the streams of the underlying suppliers. 989 * 990 * <p>Only one underlying input stream will be open at a time. Closing the 991 * joined stream will close the open underlying stream. 992 * 993 * <p>Reading from the joined stream will throw a {@link NullPointerException} 994 * if any of the suppliers are null or return null. 995 * 996 * @param suppliers the suppliers to concatenate 997 * @return a supplier that will return a stream containing the concatenated 998 * stream data 999 * @deprecated Use {@link ByteSource#concat(Iterable)} instead. This method 1000 * is scheduled for removal in Guava 18.0. 1001 */ 1002 @Deprecated 1003 public static InputSupplier<InputStream> join( 1004 final Iterable<? extends InputSupplier<? extends InputStream>> suppliers) { 1005 checkNotNull(suppliers); 1006 Iterable<ByteSource> sources = Iterables.transform(suppliers, 1007 new Function<InputSupplier<? extends InputStream>, ByteSource>() { 1008 @Override 1009 public ByteSource apply(InputSupplier<? extends InputStream> input) { 1010 return asByteSource(input); 1011 } 1012 }); 1013 return asInputSupplier(ByteSource.concat(sources)); 1014 } 1015 1016 /** 1017 * Varargs form of {@link #join(Iterable)}. 1018 * 1019 * @deprecated Use {@link ByteSource#concat(ByteSource[])} instead. This 1020 * method is scheduled for removal in Guava 18.0. 1021 */ 1022 @Deprecated 1023 @SuppressWarnings("unchecked") // suppress "possible heap pollution" warning in JDK7 1024 public static InputSupplier<InputStream> join( 1025 InputSupplier<? extends InputStream>... suppliers) { 1026 return join(Arrays.asList(suppliers)); 1027 } 1028 1029 /** 1030 * Returns a view of the given {@code InputStream} supplier as a 1031 * {@code ByteSource}. 1032 * 1033 * <p>This method is a temporary method provided for easing migration from 1034 * suppliers to sources and sinks. 1035 * 1036 * @since 15.0 1037 * @deprecated Convert all {@code InputSupplier<? extends InputStream>} 1038 * implementations to extend {@link ByteSource} or provide a method for 1039 * viewing the object as a {@code ByteSource}. This method is scheduled 1040 * for removal in Guava 18.0. 1041 */ 1042 @Deprecated 1043 public static ByteSource asByteSource( 1044 final InputSupplier<? extends InputStream> supplier) { 1045 checkNotNull(supplier); 1046 return new ByteSource() { 1047 @Override 1048 public InputStream openStream() throws IOException { 1049 return supplier.getInput(); 1050 } 1051 1052 @Override 1053 public String toString() { 1054 return "ByteStreams.asByteSource(" + supplier + ")"; 1055 } 1056 }; 1057 } 1058 1059 /** 1060 * Returns a view of the given {@code OutputStream} supplier as a 1061 * {@code ByteSink}. 1062 * 1063 * <p>This method is a temporary method provided for easing migration from 1064 * suppliers to sources and sinks. 1065 * 1066 * @since 15.0 1067 * @deprecated Convert all {@code OutputSupplier<? extends OutputStream>} 1068 * implementations to extend {@link ByteSink} or provide a method for 1069 * viewing the object as a {@code ByteSink}. This method is scheduled 1070 * for removal in Guava 18.0. 1071 */ 1072 @Deprecated 1073 public static ByteSink asByteSink( 1074 final OutputSupplier<? extends OutputStream> supplier) { 1075 checkNotNull(supplier); 1076 return new ByteSink() { 1077 @Override 1078 public OutputStream openStream() throws IOException { 1079 return supplier.getOutput(); 1080 } 1081 1082 @Override 1083 public String toString() { 1084 return "ByteStreams.asByteSink(" + supplier + ")"; 1085 } 1086 }; 1087 } 1088 1089 @SuppressWarnings("unchecked") // used internally where known to be safe 1090 static <S extends InputStream> InputSupplier<S> asInputSupplier( 1091 final ByteSource source) { 1092 return (InputSupplier) checkNotNull(source); 1093 } 1094 1095 @SuppressWarnings("unchecked") // used internally where known to be safe 1096 static <S extends OutputStream> OutputSupplier<S> asOutputSupplier( 1097 final ByteSink sink) { 1098 return (OutputSupplier) checkNotNull(sink); 1099 } 1100}