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}