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 {
137     private static final int DEFAULT_BUFFER_SIZE = 1024 * 16;
138 
139     /**
140      * Private constructor to prevent instantiation.
141      */
142     private IOUtil()
143     {
144     }
145 
146     ///////////////////////////////////////////////////////////////
147     // Core copy methods
148     ///////////////////////////////////////////////////////////////
149 
150     /**
151      * Copy bytes from an <code>InputStream</code> to an <code>OutputStream</code>.
152      * @param input to convert
153      * @param output the result
154      * @throws IOException io issue
155      */
156     public static void copy( final InputStream input, final OutputStream output )
157         throws IOException
158     {
159         BaseIOUtil.copy( input, output );
160     }
161 
162     /**
163      * Copy bytes from an <code>InputStream</code> to an <code>OutputStream</code>.
164      * @param input to convert
165      * @param output the result
166      * @param bufferSize Size of internal buffer to use.
167      * @throws IOException io issue
168      */
169     public static void copy( final InputStream input, final OutputStream output, final int bufferSize )
170         throws IOException
171     {
172         final byte[] buffer = new byte[bufferSize];
173         int n = 0;
174         while ( 0 <= ( n = input.read( buffer ) ) )
175         {
176             output.write( buffer, 0, n );
177         }
178     }
179 
180     /**
181      * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
182      * @param input to convert
183      * @param output the result
184      * @throws IOException io issue
185      */
186     public static void copy( final Reader input, final Writer output )
187         throws IOException
188     {
189         BaseIOUtil.copy( input, output );
190     }
191 
192     /**
193      * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
194      * @param input to convert
195      * @param output the result
196      * @param bufferSize Size of internal buffer to use.
197      * @throws IOException io issue
198      */
199     public static void copy( final Reader input, final Writer output, final int bufferSize )
200         throws IOException
201     {
202         final char[] buffer = new char[bufferSize];
203         int n = 0;
204         while ( 0 <= ( n = input.read( buffer ) ) )
205         {
206             output.write( buffer, 0, n );
207         }
208         output.flush();
209     }
210 
211     ///////////////////////////////////////////////////////////////
212     // Derived copy methods
213     // InputStream -> *
214     ///////////////////////////////////////////////////////////////
215 
216     ///////////////////////////////////////////////////////////////
217     // InputStream -> Writer
218 
219     /**
220      * Copy and convert bytes from an <code>InputStream</code> to chars on a <code>Writer</code>. The platform's default
221      * encoding is used for the byte-to-char conversion.
222      * @param input to convert
223      * @param output the result
224      * @throws IOException io issue
225      */
226     public static void copy( final InputStream input, final Writer output )
227         throws IOException
228     {
229         copy( input, output, DEFAULT_BUFFER_SIZE );
230     }
231 
232     /**
233      * Copy and convert bytes from an <code>InputStream</code> to chars on a <code>Writer</code>. The platform's default
234      * encoding is used for the byte-to-char conversion.
235      * @param input to convert
236      * @param output the result
237      * @param bufferSize Size of internal buffer to use.
238      * @throws IOException io issue
239      */
240     public static void copy( final InputStream input, final Writer output, final int bufferSize )
241         throws IOException
242     {
243         final InputStreamReader in = new InputStreamReader( input );
244         copy( in, output, bufferSize );
245     }
246 
247     /**
248      * Copy and convert bytes from an <code>InputStream</code> to chars on a <code>Writer</code>, using the specified
249      * encoding.
250      * @param input to convert
251      * @param output the result
252      * @param encoding The name of a supported character encoding. See the
253      *            <a href="http://www.iana.org/assignments/character-sets">IANA Charset Registry</a> for a list of valid
254      *            encoding types.
255      * @throws IOException io issue
256      */
257     public static void copy( final InputStream input, final Writer output, final String encoding )
258         throws IOException
259     {
260         final InputStreamReader in = new InputStreamReader( input, encoding );
261         copy( in, output );
262     }
263 
264     /**
265      * Copy and convert bytes from an <code>InputStream</code> to chars on a <code>Writer</code>, using the specified
266      * encoding.
267      * @param input to convert
268      * @param output the result
269      * @param encoding The name of a supported character encoding. See the
270      *            <a href="http://www.iana.org/assignments/character-sets">IANA Charset Registry</a> for a list of valid
271      *            encoding types.
272      * @param bufferSize Size of internal buffer to use.
273      * @throws IOException io issue
274      */
275     public static void copy( final InputStream input, final Writer output, final String encoding, final int bufferSize )
276         throws IOException
277     {
278         final InputStreamReader in = new InputStreamReader( input, encoding );
279         copy( in, output, bufferSize );
280     }
281 
282     ///////////////////////////////////////////////////////////////
283     // InputStream -> String
284 
285     /**
286      * @return Get the contents of an <code>InputStream</code> as a String. The platform's default encoding is used for the
287      * byte-to-char conversion.
288      * @param input to convert
289      * @throws IOException io issue
290      */
291     public static String toString( final InputStream input )
292         throws IOException
293     {
294         return toString( input, DEFAULT_BUFFER_SIZE );
295     }
296 
297     /**
298      * @return Get the contents of an <code>InputStream</code> as a String. The platform's default encoding is used for the
299      * byte-to-char conversion.
300      * @param input to convert
301      * @param bufferSize Size of internal buffer to use.
302      * @throws IOException io issue
303      */
304     public static String toString( final InputStream input, final int bufferSize )
305         throws IOException
306     {
307         final StringWriter sw = new StringWriter();
308         copy( input, sw, bufferSize );
309         return sw.toString();
310     }
311 
312     /**
313      * @return Get the contents of an <code>InputStream</code> as a String.
314      * @param input to convert
315      * @param encoding The name of a supported character encoding. See the
316      *            <a href="http://www.iana.org/assignments/character-sets">IANA Charset Registry</a> for a list of valid
317      *            encoding types.
318      * @throws IOException io issue
319      */
320     public static String toString( final InputStream input, final String encoding )
321         throws IOException
322     {
323         return toString( input, encoding, DEFAULT_BUFFER_SIZE );
324     }
325 
326     /**
327      * @return Get the contents of an <code>InputStream</code> as a String.
328      * @param input to convert
329      * @param encoding The name of a supported character encoding. See the
330      *            <a href="http://www.iana.org/assignments/character-sets">IANA Charset Registry</a> for a list of valid
331      *            encoding types.
332      * @param bufferSize Size of internal buffer to use.
333      * @throws IOException io issue
334      */
335     public static String toString( final InputStream input, final String encoding, final int bufferSize )
336         throws IOException
337     {
338         final StringWriter sw = new StringWriter();
339         copy( input, sw, encoding, bufferSize );
340         return sw.toString();
341     }
342 
343     ///////////////////////////////////////////////////////////////
344     // InputStream -> byte[]
345 
346     /**
347      * @return Get the contents of an <code>InputStream</code> as a <code>byte[]</code>.
348      * @param input to convert
349      * @throws IOException io issue
350      */
351     public static byte[] toByteArray( final InputStream input )
352         throws IOException
353     {
354         return toByteArray( input, DEFAULT_BUFFER_SIZE );
355     }
356 
357     /**
358      * @return Get the contents of an <code>InputStream</code> as a <code>byte[]</code>.
359      * @param input to convert
360      * @param bufferSize Size of internal buffer to use.
361      * @throws IOException io issue
362      */
363     public static byte[] toByteArray( final InputStream input, final int bufferSize )
364         throws IOException
365     {
366         final ByteArrayOutputStream output = new ByteArrayOutputStream();
367         copy( input, output, bufferSize );
368         return output.toByteArray();
369     }
370 
371     ///////////////////////////////////////////////////////////////
372     // Derived copy methods
373     // Reader -> *
374     ///////////////////////////////////////////////////////////////
375 
376     ///////////////////////////////////////////////////////////////
377     // Reader -> OutputStream
378     /**
379      * Serialize chars from a <code>Reader</code> to bytes on an <code>OutputStream</code>, and flush the
380      * <code>OutputStream</code>.
381      * @param input to convert
382      * @param output the result
383      * @throws IOException io issue
384      */
385     public static void copy( final Reader input, final OutputStream output )
386         throws IOException
387     {
388         copy( input, output, DEFAULT_BUFFER_SIZE );
389     }
390 
391     /**
392      * Serialize chars from a <code>Reader</code> to bytes on an <code>OutputStream</code>, and flush the
393      * <code>OutputStream</code>.
394      * @param input to convert
395      * @param output the result
396      * @param bufferSize Size of internal buffer to use.
397      * @throws IOException io issue
398      */
399     public static void copy( final Reader input, final OutputStream output, final int bufferSize )
400         throws IOException
401     {
402         final OutputStreamWriter out = new OutputStreamWriter( output );
403         copy( input, out, bufferSize );
404         // NOTE: Unless anyone is planning on rewriting OutputStreamWriter, we have to flush
405         // here.
406         out.flush();
407     }
408 
409     ///////////////////////////////////////////////////////////////
410     // Reader -> String
411     /**
412      * @return Get the contents of a <code>Reader</code> as a String.
413      * @param input to convert
414      * @throws IOException io issue
415      */
416     public static String toString( final Reader input )
417         throws IOException
418     {
419         return toString( input, DEFAULT_BUFFER_SIZE );
420     }
421 
422     /**
423      * @return Get the contents of a <code>Reader</code> as a String.
424      * @param input to convert
425      * @param bufferSize Size of internal buffer to use.
426      * @throws IOException io issue
427      */
428     public static String toString( final Reader input, final int bufferSize )
429         throws IOException
430     {
431         final StringWriter sw = new StringWriter();
432         copy( input, sw, bufferSize );
433         return sw.toString();
434     }
435 
436     ///////////////////////////////////////////////////////////////
437     // Reader -> byte[]
438     /**
439      * @return Get the contents of a <code>Reader</code> as a <code>byte[]</code>.
440      * @param input to convert
441      * @throws IOException io issue
442      */
443     public static byte[] toByteArray( final Reader input )
444         throws IOException
445     {
446         return toByteArray( input, DEFAULT_BUFFER_SIZE );
447     }
448 
449     /**
450      * @return Get the contents of a <code>Reader</code> as a <code>byte[]</code>.
451      * @param input to convert
452      * @param bufferSize Size of internal buffer to use.
453      * @throws IOException io issue
454      */
455     public static byte[] toByteArray( final Reader input, final int bufferSize )
456         throws IOException
457     {
458         ByteArrayOutputStream output = new ByteArrayOutputStream();
459         copy( input, output, bufferSize );
460         return output.toByteArray();
461     }
462 
463     ///////////////////////////////////////////////////////////////
464     // Derived copy methods
465     // String -> *
466     ///////////////////////////////////////////////////////////////
467 
468     ///////////////////////////////////////////////////////////////
469     // String -> OutputStream
470 
471     /**
472      * Serialize chars from a <code>String</code> to bytes on an <code>OutputStream</code>, and flush the
473      * <code>OutputStream</code>.
474      * @param input to convert
475      * @param output the result
476      * @throws IOException io issue
477      */
478     public static void copy( final String input, final OutputStream output )
479         throws IOException
480     {
481         copy( input, output, DEFAULT_BUFFER_SIZE );
482     }
483 
484     /**
485      * Serialize chars from a <code>String</code> to bytes on an <code>OutputStream</code>, and flush the
486      * <code>OutputStream</code>.
487      * @param input to convert
488      * @param output the result   
489      * @param bufferSize Size of internal buffer to use.
490      * @throws IOException io issue
491      */
492     public static void copy( final String input, final OutputStream output, final int bufferSize )
493         throws IOException
494     {
495         final StringReader in = new StringReader( input );
496         final OutputStreamWriter out = new OutputStreamWriter( output );
497         copy( in, out, bufferSize );
498         // NOTE: Unless anyone is planning on rewriting OutputStreamWriter, we have to flush
499         // here.
500         out.flush();
501     }
502 
503     ///////////////////////////////////////////////////////////////
504     // String -> Writer
505 
506     /**
507      * Copy chars from a <code>String</code> to a <code>Writer</code>.
508      * @param input to convert
509      * @param output the result
510      * @throws IOException io issue
511      */
512     public static void copy( final String input, final Writer output )
513         throws IOException
514     {
515         output.write( input );
516     }
517 
518     /**
519      * Copy bytes from an <code>InputStream</code> to an <code>OutputStream</code>, with buffering. This is equivalent
520      * to passing a {@link java.io.BufferedInputStream} and {@link java.io.BufferedOutputStream} to
521      * {@link #copy(InputStream, OutputStream)}, and flushing the output stream afterwards. The streams are not closed
522      * after the copy.
523      * @param input to convert
524      * @param output the result  
525      * @deprecated Buffering streams is actively harmful! See the class description as to why. Use
526      *             {@link #copy(InputStream, OutputStream)} instead.
527      * @throws IOException io issue
528      */
529     @Deprecated
530     public static void bufferedCopy( final InputStream input, final OutputStream output )
531         throws IOException
532     {
533         final BufferedInputStream in = new BufferedInputStream( input );
534         final BufferedOutputStream out = new BufferedOutputStream( output );
535         copy( in, out );
536         out.flush();
537     }
538 
539     ///////////////////////////////////////////////////////////////
540     // String -> byte[]
541     /**
542      * @return Get the contents of a <code>String</code> as a <code>byte[]</code>.
543      * @param input to convert
544      * @throws IOException io issue
545      */
546     public static byte[] toByteArray( final String input )
547         throws IOException
548     {
549         return toByteArray( input, DEFAULT_BUFFER_SIZE );
550     }
551 
552     /**
553      * @return Get the contents of a <code>String</code> as a <code>byte[]</code>.
554      * @param input to convert
555      * @param bufferSize Size of internal buffer to use.
556      * @throws IOException io issue
557      */
558     public static byte[] toByteArray( final String input, final int bufferSize )
559         throws IOException
560     {
561         ByteArrayOutputStream output = new ByteArrayOutputStream();
562         copy( input, output, bufferSize );
563         return output.toByteArray();
564     }
565 
566     ///////////////////////////////////////////////////////////////
567     // Derived copy methods
568     // byte[] -> *
569     ///////////////////////////////////////////////////////////////
570 
571     ///////////////////////////////////////////////////////////////
572     // byte[] -> Writer
573 
574     /**
575      * Copy and convert bytes from a <code>byte[]</code> to chars on a <code>Writer</code>. The platform's default
576      * encoding is used for the byte-to-char conversion.
577      * @param input to convert
578      * @param output the result
579      * @throws IOException io issue
580      */
581     public static void copy( final byte[] input, final Writer output )
582         throws IOException
583     {
584         copy( input, output, DEFAULT_BUFFER_SIZE );
585     }
586 
587     /**
588      * Copy and convert bytes from a <code>byte[]</code> to chars on a <code>Writer</code>. The platform's default
589      * encoding is used for the byte-to-char conversion.
590      * @param input to convert
591      * @param output the result  
592      * @param bufferSize Size of internal buffer to use.
593      * @throws IOException io issue
594      */
595     public static void copy( final byte[] input, final Writer output, final int bufferSize )
596         throws IOException
597     {
598         final ByteArrayInputStream in = new ByteArrayInputStream( input );
599         copy( in, output, bufferSize );
600     }
601 
602     /**
603      * Copy and convert bytes from a <code>byte[]</code> to chars on a <code>Writer</code>, using the specified
604      * encoding.
605      * @param input to convert
606      * @param output the result  
607      * @param encoding The name of a supported character encoding. See the
608      *            <a href="http://www.iana.org/assignments/character-sets">IANA Charset Registry</a> for a list of valid
609      *            encoding types.
610      * @throws IOException io issue
611      */
612     public static void copy( final byte[] input, final Writer output, final String encoding )
613         throws IOException
614     {
615         final ByteArrayInputStream in = new ByteArrayInputStream( input );
616         copy( in, output, encoding );
617     }
618 
619     /**
620      * Copy and convert bytes from a <code>byte[]</code> to chars on a <code>Writer</code>, using the specified
621      * encoding.
622      * @param input to convert
623      * @param output the result  
624      * @param encoding The name of a supported character encoding. See the
625      *            <a href="http://www.iana.org/assignments/character-sets">IANA Charset Registry</a> for a list of valid
626      *            encoding types.
627      * @param bufferSize Size of internal buffer to use.
628      * @throws IOException io issue
629      */
630     public static void copy( final byte[] input, final Writer output, final String encoding, final int bufferSize )
631         throws IOException
632     {
633         final ByteArrayInputStream in = new ByteArrayInputStream( input );
634         copy( in, output, encoding, bufferSize );
635     }
636 
637     ///////////////////////////////////////////////////////////////
638     // byte[] -> String
639 
640     /**
641      * @return Get the contents of a <code>byte[]</code> as a String. The platform's default encoding is used for the
642      * byte-to-char conversion.
643      * @param input to convert
644      * @throws IOException io issue
645      */
646     public static String toString( final byte[] input )
647         throws IOException
648     {
649         return toString( input, DEFAULT_BUFFER_SIZE );
650     }
651 
652     /**
653      * @return Get the contents of a <code>byte[]</code> as a String. The platform's default encoding is used for the
654      * byte-to-char conversion.
655      * @param input to convert
656      * @param bufferSize Size of internal buffer to use.
657      * @throws IOException io issue
658      */
659     public static String toString( final byte[] input, final int bufferSize )
660         throws IOException
661     {
662         final StringWriter sw = new StringWriter();
663         copy( input, sw, bufferSize );
664         return sw.toString();
665     }
666 
667     /**
668      * @return Get the contents of a <code>byte[]</code> as a String.
669      * @param input to convert
670      * @param encoding The name of a supported character encoding. See the
671      *            <a href="http://www.iana.org/assignments/character-sets">IANA Charset Registry</a> for a list of valid
672      *            encoding types.
673      * @throws IOException io issue
674      */
675     public static String toString( final byte[] input, final String encoding )
676         throws IOException
677     {
678         return toString( input, encoding, DEFAULT_BUFFER_SIZE );
679     }
680 
681     /**
682      * @return the contents of a <code>byte[]</code> as a String.
683      * @param input to convert
684      * @param encoding The name of a supported character encoding. See the
685      *            <a href="http://www.iana.org/assignments/character-sets">IANA Charset Registry</a> for a list of valid
686      *            encoding types.
687      * @param bufferSize Size of internal buffer to use.
688      *
689      * @throws IOException io issue
690      */
691     public static String toString( final byte[] input, final String encoding, final int bufferSize )
692         throws IOException
693     {
694         final StringWriter sw = new StringWriter();
695         copy( input, sw, encoding, bufferSize );
696         return sw.toString();
697     }
698 
699     ///////////////////////////////////////////////////////////////
700     // byte[] -> OutputStream
701 
702     /**
703      * Copy bytes from a <code>byte[]</code> to an <code>OutputStream</code>.
704      * @param input to convert
705      * @param output the result
706      * @throws IOException io issue
707      */
708     public static void copy( final byte[] input, final OutputStream output )
709         throws IOException
710     {
711         copy( input, output, DEFAULT_BUFFER_SIZE );
712     }
713 
714     /**
715      * Copy bytes from a <code>byte[]</code> to an <code>OutputStream</code>.
716      * @param input to convert
717      * @param output the result
718      * @param bufferSize Size of internal buffer to use.
719      * @throws IOException io issue
720      */
721     public static void copy( final byte[] input, final OutputStream output, final int bufferSize )
722         throws IOException
723     {
724         output.write( input );
725     }
726 
727     /**
728      * Compare the contents of two Streams to determine if they are equal or not.
729      *
730      * @param input1 the first stream
731      * @param input2 the second stream
732      * @return true if the content of the streams are equal or they both don't exist, false otherwise
733      * @throws IOException io issue
734      */
735     public static boolean contentEquals( final InputStream input1, final InputStream input2 )
736         throws IOException
737     {
738         final InputStream bufferedInput1 = new BufferedInputStream( input1 );
739         final InputStream bufferedInput2 = new BufferedInputStream( input2 );
740 
741         int ch = bufferedInput1.read();
742         while ( 0 <= ch )
743         {
744             final int ch2 = bufferedInput2.read();
745             if ( ch != ch2 )
746             {
747                 return false;
748             }
749             ch = bufferedInput1.read();
750         }
751 
752         final int ch2 = bufferedInput2.read();
753         if ( 0 <= ch2 )
754         {
755             return false;
756         }
757         else
758         {
759             return true;
760         }
761     }
762 
763     // ----------------------------------------------------------------------
764     // closeXXX()
765     // ----------------------------------------------------------------------
766 
767     /**
768      * Closes the input stream. The input stream can be null and any IOException's will be swallowed.
769      * 
770      * @param inputStream The stream to close.
771      * @deprecated use try-with-resources instead
772      */
773     @Deprecated
774     public static void close( InputStream inputStream )
775     {
776         if ( inputStream == null )
777         {
778             return;
779         }
780 
781         try
782         {
783             inputStream.close();
784         }
785         catch ( IOException ex )
786         {
787             // ignore
788         }
789     }
790 
791     /**
792      * Closes a channel. Channel can be null and any IOException's will be swallowed.
793      *
794      * @param channel The stream to close.
795      * @deprecated use try-with-resources instead
796      */
797     @Deprecated
798     public static void close( Channel channel )
799     {
800         if ( channel == null )
801         {
802             return;
803         }
804 
805         try
806         {
807             channel.close();
808         }
809         catch ( IOException ex )
810         {
811             // ignore
812         }
813     }
814 
815     /**
816      * Closes the output stream. The output stream can be null and any IOException's will be swallowed.
817      * 
818      * @param outputStream The stream to close.
819      * @deprecated use try-with-resources instead
820      */
821     @Deprecated
822     public static void close( OutputStream outputStream )
823     {
824         if ( outputStream == null )
825         {
826             return;
827         }
828 
829         try
830         {
831             outputStream.close();
832         }
833         catch ( IOException ex )
834         {
835             // ignore
836         }
837     }
838 
839     /**
840      * Closes the reader. The reader can be null and any IOException's will be swallowed.
841      * 
842      * @param reader The reader to close.
843      * @deprecated use try-with-resources instead
844      */
845     @Deprecated
846     public static void close( Reader reader )
847     {
848         if ( reader == null )
849         {
850             return;
851         }
852 
853         try
854         {
855             reader.close();
856         }
857         catch ( IOException ex )
858         {
859             // ignore
860         }
861     }
862 
863     /**
864      * Closes the writer. The writer can be null and any IOException's will be swallowed.
865      * 
866      * @param writer The writer to close.
867      * @deprecated use try-with-resources instead
868      */
869     @Deprecated
870     public static void close( Writer writer )
871     {
872         if ( writer == null )
873         {
874             return;
875         }
876 
877         try
878         {
879             writer.close();
880         }
881         catch ( IOException ex )
882         {
883             // ignore
884         }
885     }
886 }