View Javadoc
1   package org.codehaus.plexus.util;
2   
3   /* ====================================================================
4    * The Apache Software License, Version 1.1
5    *
6    * Copyright (c) 2001 The Apache Software Foundation.  All rights
7    * reserved.
8    *
9    * Redistribution and use in source and binary forms, with or without
10   * modification, are permitted provided that the following conditions
11   * are met:
12   *
13   * 1. Redistributions of source code must retain the above copyright
14   *    notice, this list of conditions and the following disclaimer.
15   *
16   * 2. Redistributions in binary form must reproduce the above copyright
17   *    notice, this list of conditions and the following disclaimer in
18   *    the documentation and/or other materials provided with the
19   *    distribution.
20   *
21   * 3. The end-user documentation included with the redistribution,
22   *    if any, must include the following acknowledgment:
23   *       "This product includes software developed by the
24   *        Apache Software Foundation (http://www.codehaus.org/)."
25   *    Alternately, this acknowledgment may appear in the software itself,
26   *    if and wherever such third-party acknowledgments normally appear.
27   *
28   * 4. The names "Apache" and "Apache Software Foundation" and
29   *    "Apache Turbine" must not be used to endorse or promote products
30   *    derived from this software without prior written permission. For
31   *    written permission, please contact codehaus@codehaus.org.
32   *
33   * 5. Products derived from this software may not be called "Apache",
34   *    "Apache Turbine", nor may "Apache" appear in their name, without
35   *    prior written permission of the Apache Software Foundation.
36   *
37   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48   * SUCH DAMAGE.
49   * ====================================================================
50   *
51   * This software consists of voluntary contributions made by many
52   * individuals on behalf of the Apache Software Foundation.  For more
53   * information on the Apache Software Foundation, please see
54   * <http://www.codehaus.org/>.
55   */
56  
57  import java.io.BufferedInputStream;
58  import java.io.BufferedOutputStream;
59  import java.io.ByteArrayInputStream;
60  import java.io.ByteArrayOutputStream;
61  import java.io.IOException;
62  import java.io.InputStream;
63  import java.io.InputStreamReader;
64  import java.io.OutputStream;
65  import java.io.OutputStreamWriter;
66  import java.io.Reader;
67  import java.io.StringReader;
68  import java.io.StringWriter;
69  import java.io.Writer;
70  import java.nio.channels.Channel;
71  
72  /**
73   * General IO Stream manipulation.
74   * <p>
75   * This class provides static utility methods for input/output operations, particularly buffered copying between sources
76   * (<code>InputStream</code>, <code>Reader</code>, <code>String</code> and <code>byte[]</code>) and destinations
77   * (<code>OutputStream</code>, <code>Writer</code>, <code>String</code> and <code>byte[]</code>).
78   * </p>
79   * <p>
80   * Unless otherwise noted, these <code>copy</code> methods do <em>not</em> flush or close the streams. Often, doing so
81   * would require making non-portable assumptions about the streams' origin and further use. This means that both
82   * streams' <code>close()</code> methods must be called after copying. if one omits this step, then the stream resources
83   * (sockets, file descriptors) are released when the associated Stream is garbage-collected. It is not a good idea to
84   * rely on this mechanism. For a good overview of the distinction between "memory management" and "resource management",
85   * see <a href="http://www.unixreview.com/articles/1998/9804/9804ja/ja.htm">this UnixReview article</a>
86   * </p>
87   * <p>
88   * For each <code>copy</code> method, a variant is provided that allows the caller to specify the buffer size (the
89   * default is 4k). As the buffer size can have a fairly large impact on speed, this may be worth tweaking. Often "large
90   * buffer -&gt; faster" does not hold, even for large data transfers.
91   * </p>
92   * <p>
93   * For byte-to-char methods, a <code>copy</code> variant allows the encoding to be selected (otherwise the platform
94   * default is used).
95   * </p>
96   * <p>
97   * The <code>copy</code> methods use an internal buffer when copying. It is therefore advisable <em>not</em> to
98   * deliberately wrap the stream arguments to the <code>copy</code> methods in <code>Buffered*</code> streams. For
99   * example, don't do the following:
100  * </p>
101  * <code>copy( new BufferedInputStream( in ), new BufferedOutputStream( out ) );</code>
102  * <p>
103  * The rationale is as follows:
104  * </p>
105  * <p>
106  * Imagine that an InputStream's read() is a very expensive operation, which would usually suggest wrapping in a
107  * BufferedInputStream. The BufferedInputStream works by issuing infrequent
108  * {@link java.io.InputStream#read(byte[] b, int off, int len)} requests on the underlying InputStream, to fill an
109  * internal buffer, from which further <code>read</code> requests can inexpensively get their data (until the buffer
110  * runs out).
111  * </p>
112  * <p>
113  * However, the <code>copy</code> methods do the same thing, keeping an internal buffer, populated by
114  * {@link InputStream#read(byte[] b, int off, int len)} requests. Having two buffers (or three if the destination stream
115  * is also buffered) is pointless, and the unnecessary buffer management hurts performance slightly (about 3%, according
116  * to some simple experiments).
117  * </p>
118  *
119  * @author <a href="mailto:peter@codehaus.org">Peter Donald</a>
120  * @author <a href="mailto:jefft@codehaus.org">Jeff Turner</a>
121  *
122  * @since 4.0
123  */
124 
125 /*
126  * Behold, intrepid explorers; a map of this class: Method Input Output Dependency ------ ----- ------ ------- 1 copy
127  * InputStream OutputStream (primitive) 2 copy Reader Writer (primitive) 3 copy InputStream Writer 2 4 toString
128  * InputStream String 3 5 toByteArray InputStream byte[] 1 6 copy Reader OutputStream 2 7 toString Reader String 2 8
129  * toByteArray Reader byte[] 6 9 copy String OutputStream 2 10 copy String Writer (trivial) 11 toByteArray String byte[]
130  * 9 12 copy byte[] Writer 3 13 toString byte[] String 12 14 copy byte[] OutputStream (trivial) Note that only the first
131  * two methods shuffle bytes; the rest use these two, or (if possible) copy using native Java copy methods. As there are
132  * method variants to specify buffer size and encoding, each row may correspond to up to 4 methods.
133  */
134 
135 public final class IOUtil extends BaseIOUtil {
136     private static final int DEFAULT_BUFFER_SIZE = 1024 * 16;
137 
138     /**
139      * Private constructor to prevent instantiation.
140      */
141     private IOUtil() {}
142 
143     ///////////////////////////////////////////////////////////////
144     // Core copy methods
145     ///////////////////////////////////////////////////////////////
146 
147     /**
148      * Copy bytes from an <code>InputStream</code> to an <code>OutputStream</code>.
149      * @param input to convert
150      * @param output the result
151      * @throws IOException io issue
152      */
153     public static void copy(final InputStream input, final OutputStream output) throws IOException {
154         BaseIOUtil.copy(input, output);
155     }
156 
157     /**
158      * Copy bytes from an <code>InputStream</code> to an <code>OutputStream</code>.
159      * @param input to convert
160      * @param output the result
161      * @param bufferSize Size of internal buffer to use.
162      * @throws IOException io issue
163      */
164     public static void copy(final InputStream input, final OutputStream output, final int bufferSize)
165             throws IOException {
166         final byte[] buffer = new byte[bufferSize];
167         int n = 0;
168         while (0 <= (n = input.read(buffer))) {
169             output.write(buffer, 0, n);
170         }
171     }
172 
173     /**
174      * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
175      * @param input to convert
176      * @param output the result
177      * @throws IOException io issue
178      */
179     public static void copy(final Reader input, final Writer output) throws IOException {
180         BaseIOUtil.copy(input, output);
181     }
182 
183     /**
184      * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
185      * @param input to convert
186      * @param output the result
187      * @param bufferSize Size of internal buffer to use.
188      * @throws IOException io issue
189      */
190     public static void copy(final Reader input, final Writer output, final int bufferSize) throws IOException {
191         final char[] buffer = new char[bufferSize];
192         int n = 0;
193         while (0 <= (n = input.read(buffer))) {
194             output.write(buffer, 0, n);
195         }
196         output.flush();
197     }
198 
199     ///////////////////////////////////////////////////////////////
200     // Derived copy methods
201     // InputStream -> *
202     ///////////////////////////////////////////////////////////////
203 
204     ///////////////////////////////////////////////////////////////
205     // InputStream -> Writer
206 
207     /**
208      * Copy and convert bytes from an <code>InputStream</code> to chars on a <code>Writer</code>. The platform's default
209      * encoding is used for the byte-to-char conversion.
210      * @param input to convert
211      * @param output the result
212      * @throws IOException io issue
213      */
214     public static void copy(final InputStream input, final Writer output) throws IOException {
215         copy(input, output, DEFAULT_BUFFER_SIZE);
216     }
217 
218     /**
219      * Copy and convert bytes from an <code>InputStream</code> to chars on a <code>Writer</code>. The platform's default
220      * encoding is used for the byte-to-char conversion.
221      * @param input to convert
222      * @param output the result
223      * @param bufferSize Size of internal buffer to use.
224      * @throws IOException io issue
225      */
226     public static void copy(final InputStream input, final Writer output, final int bufferSize) throws IOException {
227         final InputStreamReader in = new InputStreamReader(input);
228         copy(in, output, bufferSize);
229     }
230 
231     /**
232      * Copy and convert bytes from an <code>InputStream</code> to chars on a <code>Writer</code>, using the specified
233      * encoding.
234      * @param input to convert
235      * @param output the result
236      * @param encoding The name of a supported character encoding. See the
237      *            <a href="http://www.iana.org/assignments/character-sets">IANA Charset Registry</a> for a list of valid
238      *            encoding types.
239      * @throws IOException io issue
240      */
241     public static void copy(final InputStream input, final Writer output, final String encoding) throws IOException {
242         final InputStreamReader in = new InputStreamReader(input, encoding);
243         copy(in, output);
244     }
245 
246     /**
247      * Copy and convert bytes from an <code>InputStream</code> to chars on a <code>Writer</code>, using the specified
248      * encoding.
249      * @param input to convert
250      * @param output the result
251      * @param encoding The name of a supported character encoding. See the
252      *            <a href="http://www.iana.org/assignments/character-sets">IANA Charset Registry</a> for a list of valid
253      *            encoding types.
254      * @param bufferSize Size of internal buffer to use.
255      * @throws IOException io issue
256      */
257     public static void copy(final InputStream input, final Writer output, final String encoding, final int bufferSize)
258             throws IOException {
259         final InputStreamReader in = new InputStreamReader(input, encoding);
260         copy(in, output, bufferSize);
261     }
262 
263     ///////////////////////////////////////////////////////////////
264     // InputStream -> String
265 
266     /**
267      * @return Get the contents of an <code>InputStream</code> as a String. The platform's default encoding is used for the
268      * byte-to-char conversion.
269      * @param input to convert
270      * @throws IOException io issue
271      */
272     public static String toString(final InputStream input) throws IOException {
273         return toString(input, DEFAULT_BUFFER_SIZE);
274     }
275 
276     /**
277      * @return Get the contents of an <code>InputStream</code> as a String. The platform's default encoding is used for the
278      * byte-to-char conversion.
279      * @param input to convert
280      * @param bufferSize Size of internal buffer to use.
281      * @throws IOException io issue
282      */
283     public static String toString(final InputStream input, final int bufferSize) throws IOException {
284         final StringWriter sw = new StringWriter();
285         copy(input, sw, bufferSize);
286         return sw.toString();
287     }
288 
289     /**
290      * @return Get the contents of an <code>InputStream</code> as a String.
291      * @param input to convert
292      * @param encoding The name of a supported character encoding. See the
293      *            <a href="http://www.iana.org/assignments/character-sets">IANA Charset Registry</a> for a list of valid
294      *            encoding types.
295      * @throws IOException io issue
296      */
297     public static String toString(final InputStream input, final String encoding) throws IOException {
298         return toString(input, encoding, DEFAULT_BUFFER_SIZE);
299     }
300 
301     /**
302      * @return Get the contents of an <code>InputStream</code> as a String.
303      * @param input to convert
304      * @param encoding The name of a supported character encoding. See the
305      *            <a href="http://www.iana.org/assignments/character-sets">IANA Charset Registry</a> for a list of valid
306      *            encoding types.
307      * @param bufferSize Size of internal buffer to use.
308      * @throws IOException io issue
309      */
310     public static String toString(final InputStream input, final String encoding, final int bufferSize)
311             throws IOException {
312         final StringWriter sw = new StringWriter();
313         copy(input, sw, encoding, bufferSize);
314         return sw.toString();
315     }
316 
317     ///////////////////////////////////////////////////////////////
318     // InputStream -> byte[]
319 
320     /**
321      * @return Get the contents of an <code>InputStream</code> as a <code>byte[]</code>.
322      * @param input to convert
323      * @throws IOException io issue
324      */
325     public static byte[] toByteArray(final InputStream input) throws IOException {
326         return toByteArray(input, DEFAULT_BUFFER_SIZE);
327     }
328 
329     /**
330      * @return Get the contents of an <code>InputStream</code> as a <code>byte[]</code>.
331      * @param input to convert
332      * @param bufferSize Size of internal buffer to use.
333      * @throws IOException io issue
334      */
335     public static byte[] toByteArray(final InputStream input, final int bufferSize) throws IOException {
336         final ByteArrayOutputStream output = new ByteArrayOutputStream();
337         copy(input, output, bufferSize);
338         return output.toByteArray();
339     }
340 
341     ///////////////////////////////////////////////////////////////
342     // Derived copy methods
343     // Reader -> *
344     ///////////////////////////////////////////////////////////////
345 
346     ///////////////////////////////////////////////////////////////
347     // Reader -> OutputStream
348     /**
349      * Serialize chars from a <code>Reader</code> to bytes on an <code>OutputStream</code>, and flush the
350      * <code>OutputStream</code>.
351      * @param input to convert
352      * @param output the result
353      * @throws IOException io issue
354      */
355     public static void copy(final Reader input, final OutputStream output) throws IOException {
356         copy(input, output, DEFAULT_BUFFER_SIZE);
357     }
358 
359     /**
360      * Serialize chars from a <code>Reader</code> to bytes on an <code>OutputStream</code>, and flush the
361      * <code>OutputStream</code>.
362      * @param input to convert
363      * @param output the result
364      * @param bufferSize Size of internal buffer to use.
365      * @throws IOException io issue
366      */
367     public static void copy(final Reader input, final OutputStream output, final int bufferSize) throws IOException {
368         final OutputStreamWriter out = new OutputStreamWriter(output);
369         copy(input, out, bufferSize);
370         // NOTE: Unless anyone is planning on rewriting OutputStreamWriter, we have to flush
371         // here.
372         out.flush();
373     }
374 
375     ///////////////////////////////////////////////////////////////
376     // Reader -> String
377     /**
378      * @return Get the contents of a <code>Reader</code> as a String.
379      * @param input to convert
380      * @throws IOException io issue
381      */
382     public static String toString(final Reader input) throws IOException {
383         return toString(input, DEFAULT_BUFFER_SIZE);
384     }
385 
386     /**
387      * @return Get the contents of a <code>Reader</code> as a String.
388      * @param input to convert
389      * @param bufferSize Size of internal buffer to use.
390      * @throws IOException io issue
391      */
392     public static String toString(final Reader input, final int bufferSize) throws IOException {
393         final StringWriter sw = new StringWriter();
394         copy(input, sw, bufferSize);
395         return sw.toString();
396     }
397 
398     ///////////////////////////////////////////////////////////////
399     // Reader -> byte[]
400     /**
401      * @return Get the contents of a <code>Reader</code> as a <code>byte[]</code>.
402      * @param input to convert
403      * @throws IOException io issue
404      */
405     public static byte[] toByteArray(final Reader input) throws IOException {
406         return toByteArray(input, DEFAULT_BUFFER_SIZE);
407     }
408 
409     /**
410      * @return Get the contents of a <code>Reader</code> as a <code>byte[]</code>.
411      * @param input to convert
412      * @param bufferSize Size of internal buffer to use.
413      * @throws IOException io issue
414      */
415     public static byte[] toByteArray(final Reader input, final int bufferSize) throws IOException {
416         ByteArrayOutputStream output = new ByteArrayOutputStream();
417         copy(input, output, bufferSize);
418         return output.toByteArray();
419     }
420 
421     ///////////////////////////////////////////////////////////////
422     // Derived copy methods
423     // String -> *
424     ///////////////////////////////////////////////////////////////
425 
426     ///////////////////////////////////////////////////////////////
427     // String -> OutputStream
428 
429     /**
430      * Serialize chars from a <code>String</code> to bytes on an <code>OutputStream</code>, and flush the
431      * <code>OutputStream</code>.
432      * @param input to convert
433      * @param output the result
434      * @throws IOException io issue
435      */
436     public static void copy(final String input, final OutputStream output) throws IOException {
437         copy(input, output, DEFAULT_BUFFER_SIZE);
438     }
439 
440     /**
441      * Serialize chars from a <code>String</code> to bytes on an <code>OutputStream</code>, and flush the
442      * <code>OutputStream</code>.
443      * @param input to convert
444      * @param output the result
445      * @param bufferSize Size of internal buffer to use.
446      * @throws IOException io issue
447      */
448     public static void copy(final String input, final OutputStream output, final int bufferSize) throws IOException {
449         final StringReader in = new StringReader(input);
450         final OutputStreamWriter out = new OutputStreamWriter(output);
451         copy(in, out, bufferSize);
452         // NOTE: Unless anyone is planning on rewriting OutputStreamWriter, we have to flush
453         // here.
454         out.flush();
455     }
456 
457     ///////////////////////////////////////////////////////////////
458     // String -> Writer
459 
460     /**
461      * Copy chars from a <code>String</code> to a <code>Writer</code>.
462      * @param input to convert
463      * @param output the result
464      * @throws IOException io issue
465      */
466     public static void copy(final String input, final Writer output) throws IOException {
467         output.write(input);
468     }
469 
470     /**
471      * Copy bytes from an <code>InputStream</code> to an <code>OutputStream</code>, with buffering. This is equivalent
472      * to passing a {@link java.io.BufferedInputStream} and {@link java.io.BufferedOutputStream} to
473      * {@link #copy(InputStream, OutputStream)}, and flushing the output stream afterwards. The streams are not closed
474      * after the copy.
475      * @param input to convert
476      * @param output the result
477      * @deprecated Buffering streams is actively harmful! See the class description as to why. Use
478      *             {@link #copy(InputStream, OutputStream)} instead.
479      * @throws IOException io issue
480      */
481     @Deprecated
482     public static void bufferedCopy(final InputStream input, final OutputStream output) throws IOException {
483         final BufferedInputStream in = new BufferedInputStream(input);
484         final BufferedOutputStream out = new BufferedOutputStream(output);
485         copy(in, out);
486         out.flush();
487     }
488 
489     ///////////////////////////////////////////////////////////////
490     // String -> byte[]
491     /**
492      * @return Get the contents of a <code>String</code> as a <code>byte[]</code>.
493      * @param input to convert
494      * @throws IOException io issue
495      */
496     public static byte[] toByteArray(final String input) throws IOException {
497         return toByteArray(input, DEFAULT_BUFFER_SIZE);
498     }
499 
500     /**
501      * @return Get the contents of a <code>String</code> as a <code>byte[]</code>.
502      * @param input to convert
503      * @param bufferSize Size of internal buffer to use.
504      * @throws IOException io issue
505      */
506     public static byte[] toByteArray(final String input, final int bufferSize) throws IOException {
507         ByteArrayOutputStream output = new ByteArrayOutputStream();
508         copy(input, output, bufferSize);
509         return output.toByteArray();
510     }
511 
512     ///////////////////////////////////////////////////////////////
513     // Derived copy methods
514     // byte[] -> *
515     ///////////////////////////////////////////////////////////////
516 
517     ///////////////////////////////////////////////////////////////
518     // byte[] -> Writer
519 
520     /**
521      * Copy and convert bytes from a <code>byte[]</code> to chars on a <code>Writer</code>. The platform's default
522      * encoding is used for the byte-to-char conversion.
523      * @param input to convert
524      * @param output the result
525      * @throws IOException io issue
526      */
527     public static void copy(final byte[] input, final Writer output) throws IOException {
528         copy(input, output, DEFAULT_BUFFER_SIZE);
529     }
530 
531     /**
532      * Copy and convert bytes from a <code>byte[]</code> to chars on a <code>Writer</code>. The platform's default
533      * encoding is used for the byte-to-char conversion.
534      * @param input to convert
535      * @param output the result
536      * @param bufferSize Size of internal buffer to use.
537      * @throws IOException io issue
538      */
539     public static void copy(final byte[] input, final Writer output, final int bufferSize) throws IOException {
540         final ByteArrayInputStream in = new ByteArrayInputStream(input);
541         copy(in, output, bufferSize);
542     }
543 
544     /**
545      * Copy and convert bytes from a <code>byte[]</code> to chars on a <code>Writer</code>, using the specified
546      * encoding.
547      * @param input to convert
548      * @param output the result
549      * @param encoding The name of a supported character encoding. See the
550      *            <a href="http://www.iana.org/assignments/character-sets">IANA Charset Registry</a> for a list of valid
551      *            encoding types.
552      * @throws IOException io issue
553      */
554     public static void copy(final byte[] input, final Writer output, final String encoding) throws IOException {
555         final ByteArrayInputStream in = new ByteArrayInputStream(input);
556         copy(in, output, encoding);
557     }
558 
559     /**
560      * Copy and convert bytes from a <code>byte[]</code> to chars on a <code>Writer</code>, using the specified
561      * encoding.
562      * @param input to convert
563      * @param output the result
564      * @param encoding The name of a supported character encoding. See the
565      *            <a href="http://www.iana.org/assignments/character-sets">IANA Charset Registry</a> for a list of valid
566      *            encoding types.
567      * @param bufferSize Size of internal buffer to use.
568      * @throws IOException io issue
569      */
570     public static void copy(final byte[] input, final Writer output, final String encoding, final int bufferSize)
571             throws IOException {
572         final ByteArrayInputStream in = new ByteArrayInputStream(input);
573         copy(in, output, encoding, bufferSize);
574     }
575 
576     ///////////////////////////////////////////////////////////////
577     // byte[] -> String
578 
579     /**
580      * @return Get the contents of a <code>byte[]</code> as a String. The platform's default encoding is used for the
581      * byte-to-char conversion.
582      * @param input to convert
583      * @throws IOException io issue
584      */
585     public static String toString(final byte[] input) throws IOException {
586         return toString(input, DEFAULT_BUFFER_SIZE);
587     }
588 
589     /**
590      * @return Get the contents of a <code>byte[]</code> as a String. The platform's default encoding is used for the
591      * byte-to-char conversion.
592      * @param input to convert
593      * @param bufferSize Size of internal buffer to use.
594      * @throws IOException io issue
595      */
596     public static String toString(final byte[] input, final int bufferSize) throws IOException {
597         final StringWriter sw = new StringWriter();
598         copy(input, sw, bufferSize);
599         return sw.toString();
600     }
601 
602     /**
603      * @return Get the contents of a <code>byte[]</code> as a String.
604      * @param input to convert
605      * @param encoding The name of a supported character encoding. See the
606      *            <a href="http://www.iana.org/assignments/character-sets">IANA Charset Registry</a> for a list of valid
607      *            encoding types.
608      * @throws IOException io issue
609      */
610     public static String toString(final byte[] input, final String encoding) throws IOException {
611         return toString(input, encoding, DEFAULT_BUFFER_SIZE);
612     }
613 
614     /**
615      * @return the contents of a <code>byte[]</code> as a String.
616      * @param input to convert
617      * @param encoding The name of a supported character encoding. See the
618      *            <a href="http://www.iana.org/assignments/character-sets">IANA Charset Registry</a> for a list of valid
619      *            encoding types.
620      * @param bufferSize Size of internal buffer to use.
621      *
622      * @throws IOException io issue
623      */
624     public static String toString(final byte[] input, final String encoding, final int bufferSize) throws IOException {
625         final StringWriter sw = new StringWriter();
626         copy(input, sw, encoding, bufferSize);
627         return sw.toString();
628     }
629 
630     ///////////////////////////////////////////////////////////////
631     // byte[] -> OutputStream
632 
633     /**
634      * Copy bytes from a <code>byte[]</code> to an <code>OutputStream</code>.
635      * @param input to convert
636      * @param output the result
637      * @throws IOException io issue
638      */
639     public static void copy(final byte[] input, final OutputStream output) throws IOException {
640         copy(input, output, DEFAULT_BUFFER_SIZE);
641     }
642 
643     /**
644      * Copy bytes from a <code>byte[]</code> to an <code>OutputStream</code>.
645      * @param input to convert
646      * @param output the result
647      * @param bufferSize Size of internal buffer to use.
648      * @throws IOException io issue
649      */
650     public static void copy(final byte[] input, final OutputStream output, final int bufferSize) throws IOException {
651         output.write(input);
652     }
653 
654     /**
655      * Compare the contents of two Streams to determine if they are equal or not.
656      *
657      * @param input1 the first stream
658      * @param input2 the second stream
659      * @return true if the content of the streams are equal or they both don't exist, false otherwise
660      * @throws IOException io issue
661      */
662     public static boolean contentEquals(final InputStream input1, final InputStream input2) throws IOException {
663         final InputStream bufferedInput1 = new BufferedInputStream(input1);
664         final InputStream bufferedInput2 = new BufferedInputStream(input2);
665 
666         int ch = bufferedInput1.read();
667         while (0 <= ch) {
668             final int ch2 = bufferedInput2.read();
669             if (ch != ch2) {
670                 return false;
671             }
672             ch = bufferedInput1.read();
673         }
674 
675         final int ch2 = bufferedInput2.read();
676         if (0 <= ch2) {
677             return false;
678         } else {
679             return true;
680         }
681     }
682 
683     // ----------------------------------------------------------------------
684     // closeXXX()
685     // ----------------------------------------------------------------------
686 
687     /**
688      * Closes the input stream. The input stream can be null and any IOException's will be swallowed.
689      *
690      * @param inputStream The stream to close.
691      * @deprecated use try-with-resources instead
692      */
693     @Deprecated
694     public static void close(InputStream inputStream) {
695         if (inputStream == null) {
696             return;
697         }
698 
699         try {
700             inputStream.close();
701         } catch (IOException ex) {
702             // ignore
703         }
704     }
705 
706     /**
707      * Closes a channel. Channel can be null and any IOException's will be swallowed.
708      *
709      * @param channel The stream to close.
710      * @deprecated use try-with-resources instead
711      */
712     @Deprecated
713     public static void close(Channel channel) {
714         if (channel == null) {
715             return;
716         }
717 
718         try {
719             channel.close();
720         } catch (IOException ex) {
721             // ignore
722         }
723     }
724 
725     /**
726      * Closes the output stream. The output stream can be null and any IOException's will be swallowed.
727      *
728      * @param outputStream The stream to close.
729      * @deprecated use try-with-resources instead
730      */
731     @Deprecated
732     public static void close(OutputStream outputStream) {
733         if (outputStream == null) {
734             return;
735         }
736 
737         try {
738             outputStream.close();
739         } catch (IOException ex) {
740             // ignore
741         }
742     }
743 
744     /**
745      * Closes the reader. The reader can be null and any IOException's will be swallowed.
746      *
747      * @param reader The reader to close.
748      * @deprecated use try-with-resources instead
749      */
750     @Deprecated
751     public static void close(Reader reader) {
752         if (reader == null) {
753             return;
754         }
755 
756         try {
757             reader.close();
758         } catch (IOException ex) {
759             // ignore
760         }
761     }
762 
763     /**
764      * Closes the writer. The writer can be null and any IOException's will be swallowed.
765      *
766      * @param writer The writer to close.
767      * @deprecated use try-with-resources instead
768      */
769     @Deprecated
770     public static void close(Writer writer) {
771         if (writer == null) {
772             return;
773         }
774 
775         try {
776             writer.close();
777         } catch (IOException ex) {
778             // ignore
779         }
780     }
781 }