1 /*
2  * Copyright (C) 2007 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.io;
18 
19 import static com.google.common.base.Preconditions.checkArgument;
20 import static com.google.common.base.Preconditions.checkNotNull;
21 import static com.google.common.base.Preconditions.checkPositionIndex;
22 
23 import com.google.common.annotations.Beta;
24 import com.google.common.base.Function;
25 import com.google.common.collect.Iterables;
26 import com.google.common.hash.HashCode;
27 import com.google.common.hash.HashFunction;
28 
29 import java.io.ByteArrayInputStream;
30 import java.io.ByteArrayOutputStream;
31 import java.io.DataInput;
32 import java.io.DataInputStream;
33 import java.io.DataOutput;
34 import java.io.DataOutputStream;
35 import java.io.EOFException;
36 import java.io.FilterInputStream;
37 import java.io.IOException;
38 import java.io.InputStream;
39 import java.io.OutputStream;
40 import java.nio.ByteBuffer;
41 import java.nio.channels.ReadableByteChannel;
42 import java.nio.channels.WritableByteChannel;
43 import java.util.Arrays;
44 import java.util.zip.Checksum;
45 
46 /**
47  * Provides utility methods for working with byte arrays and I/O streams.
48  *
49  * @author Chris Nokleberg
50  * @author Colin Decker
51  * @since 1.0
52  */
53 @Beta
54 public final class ByteStreams {
55   private static final int BUF_SIZE = 0x1000; // 4K
56 
ByteStreams()57   private ByteStreams() {}
58 
59   /**
60    * Returns a factory that will supply instances of
61    * {@link ByteArrayInputStream} that read from the given byte array.
62    *
63    * @param b the input buffer
64    * @return the factory
65    * @deprecated Use {@link ByteSource#wrap(byte[])} instead. This method is
66    *     scheduled for removal in Guava 18.0.
67    */
68   @Deprecated
newInputStreamSupplier( byte[] b)69   public static InputSupplier<ByteArrayInputStream> newInputStreamSupplier(
70       byte[] b) {
71     return asInputSupplier(ByteSource.wrap(b));
72   }
73 
74   /**
75    * Returns a factory that will supply instances of
76    * {@link ByteArrayInputStream} that read from the given byte array.
77    *
78    * @param b the input buffer
79    * @param off the offset in the buffer of the first byte to read
80    * @param len the maximum number of bytes to read from the buffer
81    * @return the factory
82    * @deprecated Use {@code ByteSource.wrap(b).slice(off, len)} instead. This
83    *     method is scheduled for removal in Guava 18.0.
84    */
85   @Deprecated
newInputStreamSupplier( final byte[] b, final int off, final int len)86   public static InputSupplier<ByteArrayInputStream> newInputStreamSupplier(
87       final byte[] b, final int off, final int len) {
88     return asInputSupplier(ByteSource.wrap(b).slice(off, len));
89   }
90 
91   /**
92    * Returns a new {@link ByteSource} that reads bytes from the given byte array.
93    *
94    * @since 14.0
95    * @deprecated Use {@link ByteSource#wrap(byte[])} instead. This method is
96    *     scheduled to be removed in Guava 16.0.
97    */
98   @Deprecated
asByteSource(byte[] b)99   public static ByteSource asByteSource(byte[] b) {
100     return ByteSource.wrap(b);
101   }
102 
103   /**
104    * Writes a byte array to an output stream from the given supplier.
105    *
106    * @param from the bytes to write
107    * @param to the output supplier
108    * @throws IOException if an I/O error occurs
109    * @deprecated Use {@link ByteSink#write(byte[])} instead. This method is
110    *     scheduled for removal in Guava 18.0.
111    */
112   @Deprecated
write(byte[] from, OutputSupplier<? extends OutputStream> to)113   public static void write(byte[] from,
114       OutputSupplier<? extends OutputStream> to) throws IOException {
115     asByteSink(to).write(from);
116   }
117 
118   /**
119    * Opens input and output streams from the given suppliers, copies all
120    * bytes from the input to the output, and closes the streams.
121    *
122    * @param from the input factory
123    * @param to the output factory
124    * @return the number of bytes copied
125    * @throws IOException if an I/O error occurs
126    * @deprecated Use {@link ByteSource#copyTo(ByteSink)} instead. This method
127    *     is scheduled for removal in Guava 18.0.
128    */
129   @Deprecated
copy(InputSupplier<? extends InputStream> from, OutputSupplier<? extends OutputStream> to)130   public static long copy(InputSupplier<? extends InputStream> from,
131       OutputSupplier<? extends OutputStream> to) throws IOException {
132     return asByteSource(from).copyTo(asByteSink(to));
133   }
134 
135   /**
136    * Opens an input stream from the supplier, copies all bytes from the
137    * input to the output, and closes the input stream. Does not close
138    * or flush the output stream.
139    *
140    * @param from the input factory
141    * @param to the output stream to write to
142    * @return the number of bytes copied
143    * @throws IOException if an I/O error occurs
144    * @deprecated Use {@link ByteSource#copyTo(OutputStream)} instead. This
145    *      method is scheduled for removal in Guava 18.0.
146    */
147   @Deprecated
copy(InputSupplier<? extends InputStream> from, OutputStream to)148   public static long copy(InputSupplier<? extends InputStream> from,
149       OutputStream to) throws IOException {
150     return asByteSource(from).copyTo(to);
151   }
152 
153   /**
154    * Opens an output stream from the supplier, copies all bytes from the input
155    * to the output, and closes the output stream. Does not close or flush the
156    * input stream.
157    *
158    * @param from the input stream to read from
159    * @param to the output factory
160    * @return the number of bytes copied
161    * @throws IOException if an I/O error occurs
162    * @since 10.0
163    * @deprecated Use {@link ByteSink#writeFrom(InputStream)} instead. This
164    *     method is scheduled for removal in Guava 18.0.
165    */
166   @Deprecated
copy(InputStream from, OutputSupplier<? extends OutputStream> to)167   public static long copy(InputStream from,
168       OutputSupplier<? extends OutputStream> to) throws IOException {
169     return asByteSink(to).writeFrom(from);
170   }
171 
172   /**
173    * Copies all bytes from the input stream to the output stream.
174    * Does not close or flush either stream.
175    *
176    * @param from the input stream to read from
177    * @param to the output stream to write to
178    * @return the number of bytes copied
179    * @throws IOException if an I/O error occurs
180    */
copy(InputStream from, OutputStream to)181   public static long copy(InputStream from, OutputStream to)
182       throws IOException {
183     checkNotNull(from);
184     checkNotNull(to);
185     byte[] buf = new byte[BUF_SIZE];
186     long total = 0;
187     while (true) {
188       int r = from.read(buf);
189       if (r == -1) {
190         break;
191       }
192       to.write(buf, 0, r);
193       total += r;
194     }
195     return total;
196   }
197 
198   /**
199    * Copies all bytes from the readable channel to the writable channel.
200    * Does not close or flush either channel.
201    *
202    * @param from the readable channel to read from
203    * @param to the writable channel to write to
204    * @return the number of bytes copied
205    * @throws IOException if an I/O error occurs
206    */
copy(ReadableByteChannel from, WritableByteChannel to)207   public static long copy(ReadableByteChannel from,
208       WritableByteChannel to) throws IOException {
209     checkNotNull(from);
210     checkNotNull(to);
211     ByteBuffer buf = ByteBuffer.allocate(BUF_SIZE);
212     long total = 0;
213     while (from.read(buf) != -1) {
214       buf.flip();
215       while (buf.hasRemaining()) {
216         total += to.write(buf);
217       }
218       buf.clear();
219     }
220     return total;
221   }
222 
223   /**
224    * Reads all bytes from an input stream into a byte array.
225    * Does not close the stream.
226    *
227    * @param in the input stream to read from
228    * @return a byte array containing all the bytes from the stream
229    * @throws IOException if an I/O error occurs
230    */
toByteArray(InputStream in)231   public static byte[] toByteArray(InputStream in) throws IOException {
232     ByteArrayOutputStream out = new ByteArrayOutputStream();
233     copy(in, out);
234     return out.toByteArray();
235   }
236 
237   /**
238    * Reads all bytes from an input stream into a byte array. The given
239    * expected size is used to create an initial byte array, but if the actual
240    * number of bytes read from the stream differs, the correct result will be
241    * returned anyway.
242    */
toByteArray( InputStream in, int expectedSize)243   static byte[] toByteArray(
244       InputStream in, int expectedSize) throws IOException {
245     byte[] bytes = new byte[expectedSize];
246     int remaining = expectedSize;
247 
248     while (remaining > 0) {
249       int off = expectedSize - remaining;
250       int read = in.read(bytes, off, remaining);
251       if (read == -1) {
252         // end of stream before reading expectedSize bytes
253         // just return the bytes read so far
254         return copyOf(bytes, off);
255       }
256       remaining -= read;
257     }
258 
259     // bytes is now full
260     int b = in.read();
261     if (b == -1) {
262       return bytes;
263     }
264 
265     // the stream was longer, so read the rest normally
266     FastByteArrayOutputStream out = new FastByteArrayOutputStream();
267     out.write(b); // write the byte we read when testing for end of stream
268     copy(in, out);
269 
270     byte[] result = new byte[bytes.length + out.size()];
271     System.arraycopy(bytes, 0, result, 0, bytes.length);
272     out.writeTo(result, bytes.length);
273     return result;
274   }
275 
copyOf(byte[] array, int length)276   private static byte[] copyOf(byte[] array, int length) {
277     byte[] newArray = new byte[length];
278     System.arraycopy(array, 0, newArray, 0, length);
279     return newArray;
280   }
281 
282   /**
283    * BAOS that provides limited access to its internal byte array.
284    */
285   private static final class FastByteArrayOutputStream
286       extends ByteArrayOutputStream {
287     /**
288      * Writes the contents of the internal buffer to the given array starting
289      * at the given offset. Assumes the array has space to hold count bytes.
290      */
writeTo(byte[] b, int off)291     void writeTo(byte[] b, int off) {
292       System.arraycopy(buf, 0, b, off, count);
293     }
294   }
295 
296   /**
297    * Returns the data from a {@link InputStream} factory as a byte array.
298    *
299    * @param supplier the factory
300    * @throws IOException if an I/O error occurs
301    * @deprecated Use {@link ByteSource#read()} instead. This method is
302    *     scheduled for removal in Guava 18.0.
303    */
304   @Deprecated
toByteArray( InputSupplier<? extends InputStream> supplier)305   public static byte[] toByteArray(
306       InputSupplier<? extends InputStream> supplier) throws IOException {
307     return asByteSource(supplier).read();
308   }
309 
310   /**
311    * Returns a new {@link ByteArrayDataInput} instance to read from the {@code
312    * bytes} array from the beginning.
313    */
newDataInput(byte[] bytes)314   public static ByteArrayDataInput newDataInput(byte[] bytes) {
315     return newDataInput(new ByteArrayInputStream(bytes));
316   }
317 
318   /**
319    * Returns a new {@link ByteArrayDataInput} instance to read from the {@code
320    * bytes} array, starting at the given position.
321    *
322    * @throws IndexOutOfBoundsException if {@code start} is negative or greater
323    *     than the length of the array
324    */
newDataInput(byte[] bytes, int start)325   public static ByteArrayDataInput newDataInput(byte[] bytes, int start) {
326     checkPositionIndex(start, bytes.length);
327     return newDataInput(
328         new ByteArrayInputStream(bytes, start, bytes.length - start));
329   }
330 
331   /**
332    * Returns a new {@link ByteArrayDataInput} instance to read from the given
333    * {@code ByteArrayInputStream}. The given input stream is not reset before
334    * being read from by the returned {@code ByteArrayDataInput}.
335    *
336    * @since 17.0
337    */
newDataInput( ByteArrayInputStream byteArrayInputStream)338   public static ByteArrayDataInput newDataInput(
339       ByteArrayInputStream byteArrayInputStream) {
340     return new ByteArrayDataInputStream(checkNotNull(byteArrayInputStream));
341   }
342 
343   private static class ByteArrayDataInputStream implements ByteArrayDataInput {
344     final DataInput input;
345 
ByteArrayDataInputStream(ByteArrayInputStream byteArrayInputStream)346     ByteArrayDataInputStream(ByteArrayInputStream byteArrayInputStream) {
347       this.input = new DataInputStream(byteArrayInputStream);
348     }
349 
readFully(byte b[])350     @Override public void readFully(byte b[]) {
351       try {
352         input.readFully(b);
353       } catch (IOException e) {
354         throw new IllegalStateException(e);
355       }
356     }
357 
readFully(byte b[], int off, int len)358     @Override public void readFully(byte b[], int off, int len) {
359       try {
360         input.readFully(b, off, len);
361       } catch (IOException e) {
362         throw new IllegalStateException(e);
363       }
364     }
365 
skipBytes(int n)366     @Override public int skipBytes(int n) {
367       try {
368         return input.skipBytes(n);
369       } catch (IOException e) {
370         throw new IllegalStateException(e);
371       }
372     }
373 
readBoolean()374     @Override public boolean readBoolean() {
375       try {
376         return input.readBoolean();
377       } catch (IOException e) {
378         throw new IllegalStateException(e);
379       }
380     }
381 
readByte()382     @Override 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 
readUnsignedByte()392     @Override public int readUnsignedByte() {
393       try {
394         return input.readUnsignedByte();
395       } catch (IOException e) {
396         throw new IllegalStateException(e);
397       }
398     }
399 
readShort()400     @Override public short readShort() {
401       try {
402         return input.readShort();
403       } catch (IOException e) {
404         throw new IllegalStateException(e);
405       }
406     }
407 
readUnsignedShort()408     @Override public int readUnsignedShort() {
409       try {
410         return input.readUnsignedShort();
411       } catch (IOException e) {
412         throw new IllegalStateException(e);
413       }
414     }
415 
readChar()416     @Override public char readChar() {
417       try {
418         return input.readChar();
419       } catch (IOException e) {
420         throw new IllegalStateException(e);
421       }
422     }
423 
readInt()424     @Override public int readInt() {
425       try {
426         return input.readInt();
427       } catch (IOException e) {
428         throw new IllegalStateException(e);
429       }
430     }
431 
readLong()432     @Override public long readLong() {
433       try {
434         return input.readLong();
435       } catch (IOException e) {
436         throw new IllegalStateException(e);
437       }
438     }
439 
readFloat()440     @Override public float readFloat() {
441       try {
442         return input.readFloat();
443       } catch (IOException e) {
444         throw new IllegalStateException(e);
445       }
446     }
447 
readDouble()448     @Override public double readDouble() {
449       try {
450         return input.readDouble();
451       } catch (IOException e) {
452         throw new IllegalStateException(e);
453       }
454     }
455 
readLine()456     @Override public String readLine() {
457       try {
458         return input.readLine();
459       } catch (IOException e) {
460         throw new IllegalStateException(e);
461       }
462     }
463 
readUTF()464     @Override public String readUTF() {
465       try {
466         return input.readUTF();
467       } catch (IOException e) {
468         throw new IllegalStateException(e);
469       }
470     }
471   }
472 
473   /**
474    * Returns a new {@link ByteArrayDataOutput} instance with a default size.
475    */
newDataOutput()476   public static ByteArrayDataOutput newDataOutput() {
477     return newDataOutput(new ByteArrayOutputStream());
478   }
479 
480   /**
481    * Returns a new {@link ByteArrayDataOutput} instance sized to hold
482    * {@code size} bytes before resizing.
483    *
484    * @throws IllegalArgumentException if {@code size} is negative
485    */
newDataOutput(int size)486   public static ByteArrayDataOutput newDataOutput(int size) {
487     checkArgument(size >= 0, "Invalid size: %s", size);
488     return newDataOutput(new ByteArrayOutputStream(size));
489   }
490 
491   /**
492    * Returns a new {@link ByteArrayDataOutput} instance which writes to the
493    * given {@code ByteArrayOutputStream}. The given output stream is not reset
494    * before being written to by the returned {@code ByteArrayDataOutput} and
495    * new data will be appended to any existing content.
496    *
497    * <p>Note that if the given output stream was not empty or is modified after
498    * the {@code ByteArrayDataOutput} is created, the contract for
499    * {@link ByteArrayDataOutput#toByteArray} will not be honored (the bytes
500    * returned in the byte array may not be exactly what was written via calls to
501    * {@code ByteArrayDataOutput}).
502    *
503    * @since 17.0
504    */
newDataOutput( ByteArrayOutputStream byteArrayOutputSteam)505   public static ByteArrayDataOutput newDataOutput(
506       ByteArrayOutputStream byteArrayOutputSteam) {
507     return new ByteArrayDataOutputStream(checkNotNull(byteArrayOutputSteam));
508   }
509 
510   @SuppressWarnings("deprecation") // for writeBytes
511   private static class ByteArrayDataOutputStream
512       implements ByteArrayDataOutput {
513 
514     final DataOutput output;
515     final ByteArrayOutputStream byteArrayOutputSteam;
516 
ByteArrayDataOutputStream(ByteArrayOutputStream byteArrayOutputSteam)517     ByteArrayDataOutputStream(ByteArrayOutputStream byteArrayOutputSteam) {
518       this.byteArrayOutputSteam = byteArrayOutputSteam;
519       output = new DataOutputStream(byteArrayOutputSteam);
520     }
521 
write(int b)522     @Override public void write(int b) {
523       try {
524         output.write(b);
525       } catch (IOException impossible) {
526         throw new AssertionError(impossible);
527       }
528     }
529 
write(byte[] b)530     @Override public void write(byte[] b) {
531       try {
532         output.write(b);
533       } catch (IOException impossible) {
534         throw new AssertionError(impossible);
535       }
536     }
537 
write(byte[] b, int off, int len)538     @Override public void write(byte[] b, int off, int len) {
539       try {
540         output.write(b, off, len);
541       } catch (IOException impossible) {
542         throw new AssertionError(impossible);
543       }
544     }
545 
writeBoolean(boolean v)546     @Override public void writeBoolean(boolean v) {
547       try {
548         output.writeBoolean(v);
549       } catch (IOException impossible) {
550         throw new AssertionError(impossible);
551       }
552     }
553 
writeByte(int v)554     @Override public void writeByte(int v) {
555       try {
556         output.writeByte(v);
557       } catch (IOException impossible) {
558         throw new AssertionError(impossible);
559       }
560     }
561 
writeBytes(String s)562     @Override public void writeBytes(String s) {
563       try {
564         output.writeBytes(s);
565       } catch (IOException impossible) {
566         throw new AssertionError(impossible);
567       }
568     }
569 
writeChar(int v)570     @Override public void writeChar(int v) {
571       try {
572         output.writeChar(v);
573       } catch (IOException impossible) {
574         throw new AssertionError(impossible);
575       }
576     }
577 
writeChars(String s)578     @Override public void writeChars(String s) {
579       try {
580         output.writeChars(s);
581       } catch (IOException impossible) {
582         throw new AssertionError(impossible);
583       }
584     }
585 
writeDouble(double v)586     @Override public void writeDouble(double v) {
587       try {
588         output.writeDouble(v);
589       } catch (IOException impossible) {
590         throw new AssertionError(impossible);
591       }
592     }
593 
writeFloat(float v)594     @Override public void writeFloat(float v) {
595       try {
596         output.writeFloat(v);
597       } catch (IOException impossible) {
598         throw new AssertionError(impossible);
599       }
600     }
601 
writeInt(int v)602     @Override public void writeInt(int v) {
603       try {
604         output.writeInt(v);
605       } catch (IOException impossible) {
606         throw new AssertionError(impossible);
607       }
608     }
609 
writeLong(long v)610     @Override public void writeLong(long v) {
611       try {
612         output.writeLong(v);
613       } catch (IOException impossible) {
614         throw new AssertionError(impossible);
615       }
616     }
617 
writeShort(int v)618     @Override public void writeShort(int v) {
619       try {
620         output.writeShort(v);
621       } catch (IOException impossible) {
622         throw new AssertionError(impossible);
623       }
624     }
625 
writeUTF(String s)626     @Override public void writeUTF(String s) {
627       try {
628         output.writeUTF(s);
629       } catch (IOException impossible) {
630         throw new AssertionError(impossible);
631       }
632     }
633 
toByteArray()634     @Override public byte[] toByteArray() {
635       return byteArrayOutputSteam.toByteArray();
636     }
637   }
638 
639   private static final OutputStream NULL_OUTPUT_STREAM =
640       new OutputStream() {
641         /** Discards the specified byte. */
642         @Override public void write(int b) {
643         }
644         /** Discards the specified byte array. */
645         @Override public void write(byte[] b) {
646           checkNotNull(b);
647         }
648         /** Discards the specified byte array. */
649         @Override public void write(byte[] b, int off, int len) {
650           checkNotNull(b);
651         }
652 
653         @Override
654         public String toString() {
655           return "ByteStreams.nullOutputStream()";
656         }
657       };
658 
659   /**
660    * Returns an {@link OutputStream} that simply discards written bytes.
661    *
662    * @since 14.0 (since 1.0 as com.google.common.io.NullOutputStream)
663    */
nullOutputStream()664   public static OutputStream nullOutputStream() {
665     return NULL_OUTPUT_STREAM;
666   }
667 
668   /**
669    * Wraps a {@link InputStream}, limiting the number of bytes which can be
670    * read.
671    *
672    * @param in the input stream to be wrapped
673    * @param limit the maximum number of bytes to be read
674    * @return a length-limited {@link InputStream}
675    * @since 14.0 (since 1.0 as com.google.common.io.LimitInputStream)
676    */
limit(InputStream in, long limit)677   public static InputStream limit(InputStream in, long limit) {
678     return new LimitedInputStream(in, limit);
679   }
680 
681   private static final class LimitedInputStream extends FilterInputStream {
682 
683     private long left;
684     private long mark = -1;
685 
LimitedInputStream(InputStream in, long limit)686     LimitedInputStream(InputStream in, long limit) {
687       super(in);
688       checkNotNull(in);
689       checkArgument(limit >= 0, "limit must be non-negative");
690       left = limit;
691     }
692 
available()693     @Override public int available() throws IOException {
694       return (int) Math.min(in.available(), left);
695     }
696 
697     // it's okay to mark even if mark isn't supported, as reset won't work
mark(int readLimit)698     @Override public synchronized void mark(int readLimit) {
699       in.mark(readLimit);
700       mark = left;
701     }
702 
read()703     @Override public int read() throws IOException {
704       if (left == 0) {
705         return -1;
706       }
707 
708       int result = in.read();
709       if (result != -1) {
710         --left;
711       }
712       return result;
713     }
714 
read(byte[] b, int off, int len)715     @Override public int read(byte[] b, int off, int len) throws IOException {
716       if (left == 0) {
717         return -1;
718       }
719 
720       len = (int) Math.min(len, left);
721       int result = in.read(b, off, len);
722       if (result != -1) {
723         left -= result;
724       }
725       return result;
726     }
727 
reset()728     @Override public synchronized void reset() throws IOException {
729       if (!in.markSupported()) {
730         throw new IOException("Mark not supported");
731       }
732       if (mark == -1) {
733         throw new IOException("Mark not set");
734       }
735 
736       in.reset();
737       left = mark;
738     }
739 
skip(long n)740     @Override public long skip(long n) throws IOException {
741       n = Math.min(n, left);
742       long skipped = in.skip(n);
743       left -= skipped;
744       return skipped;
745     }
746   }
747 
748   /**
749    * Returns the length of a supplied input stream, in bytes.
750    *
751    * @deprecated Use {@link ByteSource#size()} instead. This method is
752    *     scheduled for removal in Guava 18.0.
753    */
754   @Deprecated
length( InputSupplier<? extends InputStream> supplier)755   public static long length(
756       InputSupplier<? extends InputStream> supplier) throws IOException {
757     return asByteSource(supplier).size();
758   }
759 
760   /**
761    * Returns true if the supplied input streams contain the same bytes.
762    *
763    * @throws IOException if an I/O error occurs
764    * @deprecated Use {@link ByteSource#contentEquals(ByteSource)} instead. This
765    *     method is scheduled for removal in Guava 18.0.
766    */
767   @Deprecated
equal(InputSupplier<? extends InputStream> supplier1, InputSupplier<? extends InputStream> supplier2)768   public static boolean equal(InputSupplier<? extends InputStream> supplier1,
769       InputSupplier<? extends InputStream> supplier2) throws IOException {
770     return asByteSource(supplier1).contentEquals(asByteSource(supplier2));
771   }
772 
773   /**
774    * Attempts to read enough bytes from the stream to fill the given byte array,
775    * with the same behavior as {@link DataInput#readFully(byte[])}.
776    * Does not close the stream.
777    *
778    * @param in the input stream to read from.
779    * @param b the buffer into which the data is read.
780    * @throws EOFException if this stream reaches the end before reading all
781    *     the bytes.
782    * @throws IOException if an I/O error occurs.
783    */
readFully(InputStream in, byte[] b)784   public static void readFully(InputStream in, byte[] b) throws IOException {
785     readFully(in, b, 0, b.length);
786   }
787 
788   /**
789    * Attempts to read {@code len} bytes from the stream into the given array
790    * starting at {@code off}, with the same behavior as
791    * {@link DataInput#readFully(byte[], int, int)}. Does not close the
792    * stream.
793    *
794    * @param in the input stream to read from.
795    * @param b the buffer into which the data is read.
796    * @param off an int specifying the offset into the data.
797    * @param len an int specifying the number of bytes to read.
798    * @throws EOFException if this stream reaches the end before reading all
799    *     the bytes.
800    * @throws IOException if an I/O error occurs.
801    */
readFully( InputStream in, byte[] b, int off, int len)802   public static void readFully(
803       InputStream in, byte[] b, int off, int len) throws IOException {
804     int read = read(in, b, off, len);
805     if (read != len) {
806       throw new EOFException("reached end of stream after reading "
807           + read + " bytes; " + len + " bytes expected");
808     }
809   }
810 
811   /**
812    * Discards {@code n} bytes of data from the input stream. This method
813    * will block until the full amount has been skipped. Does not close the
814    * stream.
815    *
816    * @param in the input stream to read from
817    * @param n the number of bytes to skip
818    * @throws EOFException if this stream reaches the end before skipping all
819    *     the bytes
820    * @throws IOException if an I/O error occurs, or the stream does not
821    *     support skipping
822    */
skipFully(InputStream in, long n)823   public static void skipFully(InputStream in, long n) throws IOException {
824     long toSkip = n;
825     while (n > 0) {
826       long amt = in.skip(n);
827       if (amt == 0) {
828         // Force a blocking read to avoid infinite loop
829         if (in.read() == -1) {
830           long skipped = toSkip - n;
831           throw new EOFException("reached end of stream after skipping "
832               + skipped + " bytes; " + toSkip + " bytes expected");
833         }
834         n--;
835       } else {
836         n -= amt;
837       }
838     }
839   }
840 
841   /**
842    * Process the bytes of a supplied stream
843    *
844    * @param supplier the input stream factory
845    * @param processor the object to which to pass the bytes of the stream
846    * @return the result of the byte processor
847    * @throws IOException if an I/O error occurs
848    * @deprecated Use {@link ByteSource#read(ByteProcessor)} instead. This
849    *     method is scheduled for removal in Guava 18.0.
850    */
851   @Deprecated
readBytes( InputSupplier<? extends InputStream> supplier, ByteProcessor<T> processor)852   public static <T> T readBytes(
853       InputSupplier<? extends InputStream> supplier,
854       ByteProcessor<T> processor) throws IOException {
855     checkNotNull(supplier);
856     checkNotNull(processor);
857 
858     Closer closer = Closer.create();
859     try {
860       InputStream in = closer.register(supplier.getInput());
861       return readBytes(in, processor);
862     } catch (Throwable e) {
863       throw closer.rethrow(e);
864     } finally {
865       closer.close();
866     }
867   }
868 
869   /**
870    * Process the bytes of the given input stream using the given processor.
871    *
872    * @param input the input stream to process
873    * @param processor the object to which to pass the bytes of the stream
874    * @return the result of the byte processor
875    * @throws IOException if an I/O error occurs
876    * @since 14.0
877    */
readBytes( InputStream input, ByteProcessor<T> processor)878   public static <T> T readBytes(
879       InputStream input, ByteProcessor<T> processor) throws IOException {
880     checkNotNull(input);
881     checkNotNull(processor);
882 
883     byte[] buf = new byte[BUF_SIZE];
884     int read;
885     do {
886       read = input.read(buf);
887     } while (read != -1 && processor.processBytes(buf, 0, read));
888     return processor.getResult();
889   }
890 
891   /**
892    * Computes and returns the checksum value for a supplied input stream.
893    * The checksum object is reset when this method returns successfully.
894    *
895    * @param supplier the input stream factory
896    * @param checksum the checksum object
897    * @return the result of {@link Checksum#getValue} after updating the
898    *     checksum object with all of the bytes in the stream
899    * @throws IOException if an I/O error occurs
900    * @deprecated Use {@code hash} with the {@code Hashing.crc32()} or
901    *     {@code Hashing.adler32()} hash functions instead. This method is
902    *     scheduled to be removed in Guava 15.0.
903    */
904   @Deprecated
getChecksum( InputSupplier<? extends InputStream> supplier, final Checksum checksum)905   public static long getChecksum(
906       InputSupplier<? extends InputStream> supplier, final Checksum checksum)
907       throws IOException {
908     checkNotNull(checksum);
909     return readBytes(supplier, new ByteProcessor<Long>() {
910       @Override
911       public boolean processBytes(byte[] buf, int off, int len) {
912         checksum.update(buf, off, len);
913         return true;
914       }
915       @Override
916       public Long getResult() {
917         long result = checksum.getValue();
918         checksum.reset();
919         return result;
920       }
921     });
922   }
923 
924   /**
925    * Computes the hash code of the data supplied by {@code supplier} using {@code
926    * hashFunction}.
927    *
928    * @param supplier the input stream factory
929    * @param hashFunction the hash function to use to hash the data
930    * @return the {@link HashCode} of all of the bytes in the input stream
931    * @throws IOException if an I/O error occurs
932    * @since 12.0
933    * @deprecated Use {@link ByteSource#hash(HashFunction)} instead. This method
934    *     is scheduled for removal in Guava 18.0.
935    */
936   @Deprecated
937   public static HashCode hash(
938       InputSupplier<? extends InputStream> supplier, HashFunction hashFunction)
939       throws IOException {
940     return asByteSource(supplier).hash(hashFunction);
941   }
942 
943   /**
944    * Reads some bytes from an input stream and stores them into the buffer array
945    * {@code b}. This method blocks until {@code len} bytes of input data have
946    * been read into the array, or end of file is detected. The number of bytes
947    * read is returned, possibly zero. Does not close the stream.
948    *
949    * <p>A caller can detect EOF if the number of bytes read is less than
950    * {@code len}. All subsequent calls on the same stream will return zero.
951    *
952    * <p>If {@code b} is null, a {@code NullPointerException} is thrown. If
953    * {@code off} is negative, or {@code len} is negative, or {@code off+len} is
954    * greater than the length of the array {@code b}, then an
955    * {@code IndexOutOfBoundsException} is thrown. If {@code len} is zero, then
956    * no bytes are read. Otherwise, the first byte read is stored into element
957    * {@code b[off]}, the next one into {@code b[off+1]}, and so on. The number
958    * of bytes read is, at most, equal to {@code len}.
959    *
960    * @param in the input stream to read from
961    * @param b the buffer into which the data is read
962    * @param off an int specifying the offset into the data
963    * @param len an int specifying the number of bytes to read
964    * @return the number of bytes read
965    * @throws IOException if an I/O error occurs
966    */
967   public static int read(InputStream in, byte[] b, int off, int len)
968       throws IOException {
969     checkNotNull(in);
970     checkNotNull(b);
971     if (len < 0) {
972       throw new IndexOutOfBoundsException("len is negative");
973     }
974     int total = 0;
975     while (total < len) {
976       int result = in.read(b, off + total, len - total);
977       if (result == -1) {
978         break;
979       }
980       total += result;
981     }
982     return total;
983   }
984 
985   /**
986    * Returns an {@link InputSupplier} that returns input streams from the
987    * an underlying supplier, where each stream starts at the given
988    * offset and is limited to the specified number of bytes.
989    *
990    * @param supplier the supplier from which to get the raw streams
991    * @param offset the offset in bytes into the underlying stream where
992    *     the returned streams will start
993    * @param length the maximum length of the returned streams
994    * @throws IllegalArgumentException if offset or length are negative
995    * @deprecated Use {@link ByteSource#slice(int, int)} instead. This method is
996    *     scheduled for removal in Guava 18.0.
997    */
998   @Deprecated
999   public static InputSupplier<InputStream> slice(
1000       final InputSupplier<? extends InputStream> supplier,
1001       final long offset,
1002       final long length) {
1003     return asInputSupplier(asByteSource(supplier).slice(offset, length));
1004   }
1005 
1006   /**
1007    * Joins multiple {@link InputStream} suppliers into a single supplier.
1008    * Streams returned from the supplier will contain the concatenated data from
1009    * the streams of the underlying suppliers.
1010    *
1011    * <p>Only one underlying input stream will be open at a time. Closing the
1012    * joined stream will close the open underlying stream.
1013    *
1014    * <p>Reading from the joined stream will throw a {@link NullPointerException}
1015    * if any of the suppliers are null or return null.
1016    *
1017    * @param suppliers the suppliers to concatenate
1018    * @return a supplier that will return a stream containing the concatenated
1019    *     stream data
1020    * @deprecated Use {@link ByteSource#concat(Iterable)} instead. This method
1021    *     is scheduled for removal in Guava 18.0.
1022    */
1023   @Deprecated
1024   public static InputSupplier<InputStream> join(
1025       final Iterable<? extends InputSupplier<? extends InputStream>> suppliers) {
1026     checkNotNull(suppliers);
1027     Iterable<ByteSource> sources = Iterables.transform(suppliers,
1028         new Function<InputSupplier<? extends InputStream>, ByteSource>() {
1029           @Override
1030           public ByteSource apply(InputSupplier<? extends InputStream> input) {
1031             return asByteSource(input);
1032           }
1033         });
1034     return asInputSupplier(ByteSource.concat(sources));
1035   }
1036 
1037   /**
1038    * Varargs form of {@link #join(Iterable)}.
1039    *
1040    * @deprecated Use {@link ByteSource#concat(ByteSource[])} instead. This
1041    *     method is scheduled for removal in Guava 18.0.
1042    */
1043   @Deprecated
1044   @SuppressWarnings("unchecked") // suppress "possible heap pollution" warning in JDK7
1045   public static InputSupplier<InputStream> join(
1046       InputSupplier<? extends InputStream>... suppliers) {
1047     return join(Arrays.asList(suppliers));
1048   }
1049 
1050   // TODO(user): Remove these once Input/OutputSupplier methods are removed
1051 
1052   /**
1053    * Returns a view of the given {@code InputStream} supplier as a
1054    * {@code ByteSource}.
1055    *
1056    * <p>This method is a temporary method provided for easing migration from
1057    * suppliers to sources and sinks.
1058    *
1059    * @since 15.0
1060    * @deprecated Convert all {@code InputSupplier<? extends InputStream>}
1061    *     implementations to extend {@link ByteSource} or provide a method for
1062    *     viewing the object as a {@code ByteSource}. This method is scheduled
1063    *     for removal in Guava 18.0.
1064    */
1065   @Deprecated
1066   public static ByteSource asByteSource(
1067       final InputSupplier<? extends InputStream> supplier) {
1068     checkNotNull(supplier);
1069     return new ByteSource() {
1070       @Override
1071       public InputStream openStream() throws IOException {
1072         return supplier.getInput();
1073       }
1074 
1075       @Override
1076       public String toString() {
1077         return "ByteStreams.asByteSource(" + supplier + ")";
1078       }
1079     };
1080   }
1081 
1082   /**
1083    * Returns a view of the given {@code OutputStream} supplier as a
1084    * {@code ByteSink}.
1085    *
1086    * <p>This method is a temporary method provided for easing migration from
1087    * suppliers to sources and sinks.
1088    *
1089    * @since 15.0
1090    * @deprecated Convert all {@code OutputSupplier<? extends OutputStream>}
1091    *     implementations to extend {@link ByteSink} or provide a method for
1092    *     viewing the object as a {@code ByteSink}. This method is scheduled
1093    *     for removal in Guava 18.0.
1094    */
1095   @Deprecated
1096   public static ByteSink asByteSink(
1097       final OutputSupplier<? extends OutputStream> supplier) {
1098     checkNotNull(supplier);
1099     return new ByteSink() {
1100       @Override
1101       public OutputStream openStream() throws IOException {
1102         return supplier.getOutput();
1103       }
1104 
1105       @Override
1106       public String toString() {
1107         return "ByteStreams.asByteSink(" + supplier + ")";
1108       }
1109     };
1110   }
1111 
1112   @SuppressWarnings("unchecked") // used internally where known to be safe
1113   static <S extends InputStream> InputSupplier<S> asInputSupplier(
1114       final ByteSource source) {
1115     return (InputSupplier) checkNotNull(source);
1116   }
1117 
1118   @SuppressWarnings("unchecked") // used internally where known to be safe
1119   static <S extends OutputStream> OutputSupplier<S> asOutputSupplier(
1120       final ByteSink sink) {
1121     return (OutputSupplier) checkNotNull(sink);
1122   }
1123 }
1124