View Javadoc
1   package org.apache.maven.shared.utils.io;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import javax.annotation.Nonnull;
23  import javax.annotation.Nullable;
24  
25  import java.io.BufferedInputStream;
26  import java.io.ByteArrayInputStream;
27  import java.io.ByteArrayOutputStream;
28  import java.io.IOException;
29  import java.io.InputStream;
30  import java.io.InputStreamReader;
31  import java.io.OutputStream;
32  import java.io.OutputStreamWriter;
33  import java.io.Reader;
34  import java.io.StringReader;
35  import java.io.StringWriter;
36  import java.io.Writer;
37  import java.nio.channels.Channel;
38  
39  /**
40   * General IO Stream manipulation.
41   * <p>
42   * This class provides static utility methods for input/output operations, particularly buffered
43   * copying between sources (<code>InputStream</code>, <code>Reader</code>, <code>String</code> and
44   * <code>byte[]</code>) and destinations (<code>OutputStream</code>, <code>Writer</code>,
45   * <code>String</code> and <code>byte[]</code>).
46   * </p>
47   * <p/>
48   * <p>Unless otherwise noted, these <code>copy</code> methods do <em>not</em> flush or close the
49   * streams. Often, doing so would require making non-portable assumptions about the streams' origin
50   * and further use. This means that both streams' <code>close()</code> methods must be called after
51   * copying. if one omits this step, then the stream resources (sockets, file descriptors) are
52   * released when the associated Stream is garbage-collected. It is not a good idea to rely on this
53   * mechanism. For a good overview of the distinction between "memory management" and "resource
54   * management", see <a href="http://www.unixreview.com/articles/1998/9804/9804ja/ja.htm">this
55   * UnixReview article</a></p>
56   * <p/>
57   * <p>For each <code>copy</code> method, a variant is provided that allows the caller to specify the
58   * buffer size (the default is 4k). As the buffer size can have a fairly large impact on speed, this
59   * may be worth tweaking. Often "large buffer -&gt; faster" does not hold, even for large data
60   * transfers.</p>
61   * <p/>
62   * <p>For byte-to-char methods, a <code>copy</code> variant allows the encoding to be selected
63   * (otherwise the platform default is used).</p>
64   * <p/>
65   * <p>The <code>copy</code> methods use an internal buffer when copying. It is therefore advisable
66   * <em>not</em> to deliberately wrap the stream arguments to the <code>copy</code> methods in
67   * <code>Buffered*</code> streams. For example, don't do the
68   * following:</p>
69   * <p/>
70   * <code>copy( new BufferedInputStream( in ), new BufferedOutputStream( out ) );</code>
71   * <p/>
72   * <p>The rationale is as follows:</p>
73   * <p/>
74   * <p>Imagine that an InputStream's read() is a very expensive operation, which would usually suggest
75   * wrapping in a BufferedInputStream. The BufferedInputStream works by issuing infrequent
76   * {@link java.io.InputStream#read(byte[] b, int off, int len)} requests on the underlying InputStream, to
77   * fill an internal buffer, from which further <code>read</code> requests can inexpensively get
78   * their data (until the buffer runs out).</p>
79   * <p>However, the <code>copy</code> methods do the same thing, keeping an internal buffer,
80   * populated by {@link InputStream#read(byte[] b, int off, int len)} requests. Having two buffers
81   * (or three if the destination stream is also buffered) is pointless, and the unnecessary buffer
82   * management hurts performance slightly (about 3%, according to some simple experiments).</p>
83   *
84   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
85   * @author <a href="mailto:jefft@apache.org">Jeff Turner</a>
86   * @version CVS $Revision: 1750548 $ $Date: 2016-06-28 19:32:21 +0200 (Tue, 28 Jun 2016) $
87   *
88   */
89  public final class IOUtil
90  /*
91   * Behold, intrepid explorers; a map of this class:
92   *
93   *       Method      Input               Output          Dependency
94   *       ------      -----               ------          -------
95   * 1     copy        InputStream         OutputStream    (primitive)
96   * 2     copy        Reader              Writer          (primitive)
97   *
98   * 3     copy        InputStream         Writer          2
99   * 4     toString    InputStream         String          3
100  * 5     toByteArray InputStream         byte[]          1
101  *
102  * 6     copy        Reader              OutputStream    2
103  * 7     toString    Reader              String          2
104  * 8     toByteArray Reader              byte[]          6
105  *
106  * 9     copy        String              OutputStream    2
107  * 10    copy        String              Writer          (trivial)
108  * 11    toByteArray String              byte[]          9
109  *
110  * 12    copy        byte[]              Writer          3
111  * 13    toString    byte[]              String          12
112  * 14    copy        byte[]              OutputStream    (trivial)
113  *
114  *
115  * Note that only the first two methods shuffle bytes; the rest use these two, or (if possible) copy
116  * using native Java copy methods. As there are method variants to specify buffer size and encoding,
117  * each row may correspond to up to 4 methods.
118  *
119  */
120 {
121     private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
122 
123     /**
124      * Private constructor to prevent instantiation.
125      */
126     private IOUtil()
127     {
128     }
129 
130     ///////////////////////////////////////////////////////////////
131     // Core copy methods
132     ///////////////////////////////////////////////////////////////
133 
134     /**
135      * Copy bytes from an <code>InputStream</code> to an <code>OutputStream</code>.
136      * @param input The input size.
137      * @param output The resulting output.
138      * @throws IOException in case of an error.
139      */
140     public static void copy( @Nonnull final InputStream input, @Nonnull final OutputStream output )
141         throws IOException
142     {
143         copy( input, output, DEFAULT_BUFFER_SIZE );
144     }
145 
146     /**
147      * Copy bytes from an <code>InputStream</code> to an <code>OutputStream</code>.
148      *
149      * @param input The input size.
150      * @param output The resulting output.
151      * @param bufferSize Size of internal buffer to use.
152      * @throws IOException in case of an error.
153      */
154     public static void copy( @Nonnull final InputStream input, @Nonnull final OutputStream output,
155                              final int bufferSize )
156         throws IOException
157     {
158         final byte[] buffer = new byte[bufferSize];
159         int n;
160         while ( -1 != ( n = input.read( buffer ) ) )
161         {
162             output.write( buffer, 0, n );
163         }
164     }
165 
166     /**
167      * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
168      * @param input The input size.
169      * @param output The resulting output.
170      * @throws IOException in case of failure.
171      */
172     public static void copy( @Nonnull final Reader input, @Nonnull final Writer output )
173         throws IOException
174     {
175         copy( input, output, DEFAULT_BUFFER_SIZE );
176     }
177 
178     /**
179      * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
180      *
181      * @param input The input size.
182      * @param output The resulting output.
183      * @param bufferSize Size of internal buffer to use.
184      * @throws IOException in case of failure.
185      */
186     public static void copy( @Nonnull final Reader input, @Nonnull final Writer output, final int bufferSize )
187         throws IOException
188     {
189         final char[] buffer = new char[bufferSize];
190         int n;
191         while ( -1 != ( n = input.read( buffer ) ) )
192         {
193             output.write( buffer, 0, n );
194         }
195         output.flush();
196     }
197 
198     ///////////////////////////////////////////////////////////////
199     // Derived copy methods
200     // InputStream -> *
201     ///////////////////////////////////////////////////////////////
202 
203     ///////////////////////////////////////////////////////////////
204     // InputStream -> Writer
205 
206     /**
207      * Copy and convert bytes from an <code>InputStream</code> to chars on a
208      * <code>Writer</code>.
209      * The platform's default encoding is used for the byte-to-char conversion.
210      * @param input The input size.
211      * @param output The resulting output.
212      * @throws IOException in case of failure.
213      */
214     public static void copy( @Nonnull final InputStream input, @Nonnull final Writer output )
215         throws IOException
216     {
217         copy( input, output, DEFAULT_BUFFER_SIZE );
218     }
219 
220     /**
221      * Copy and convert bytes from an <code>InputStream</code> to chars on a
222      * <code>Writer</code>.
223      * The platform's default encoding is used for the byte-to-char conversion.
224      *
225      * @param input The input size.
226      * @param output The resulting output.
227      * @param bufferSize Size of internal buffer to use.
228      * @throws IOException in case of failure.
229      */
230     public static void copy( @Nonnull final InputStream input, @Nonnull final Writer output, final int bufferSize )
231         throws IOException
232     {
233         final InputStreamReader in = new InputStreamReader( input );
234         copy( in, output, bufferSize );
235     }
236 
237     /**
238      * Copy and convert bytes from an <code>InputStream</code> to chars on a
239      * <code>Writer</code>, using the specified encoding.
240      *
241      * @param input The input size.
242      * @param output The resulting output.
243      * @param encoding The name of a supported character encoding. See the
244      *                 <a href="http://www.iana.org/assignments/character-sets">IANA
245      *                 Charset Registry</a> for a list of valid encoding types.
246      * @throws IOException in case of failure.
247      */
248     public static void copy( @Nonnull final InputStream input, @Nonnull final Writer output,
249                              @Nonnull final String encoding )
250         throws IOException
251     {
252         final InputStreamReader in = new InputStreamReader( input, encoding );
253         copy( in, output );
254     }
255 
256     /**
257      * Copy and convert bytes from an <code>InputStream</code> to chars on a
258      * <code>Writer</code>, using the specified encoding.
259      *
260      * @param encoding   The name of a supported character encoding. See the
261      *                   <a href="http://www.iana.org/assignments/character-sets">IANA
262      *                   Charset Registry</a> for a list of valid encoding types.
263      * @param input The input size.
264      * @param output The resulting output.
265      * @param bufferSize Size of internal buffer to use.
266      * @throws IOException in case of failure.
267      */
268     public static void copy( @Nonnull final InputStream input, @Nonnull final Writer output,
269                              @Nonnull final String encoding, final int bufferSize )
270         throws IOException
271     {
272         final InputStreamReader in = new InputStreamReader( input, encoding );
273         copy( in, output, bufferSize );
274     }
275 
276     ///////////////////////////////////////////////////////////////
277     // InputStream -> String
278 
279     /**
280      * Get the contents of an <code>InputStream</code> as a String.
281      * The platform's default encoding is used for the byte-to-char conversion.
282      * @param input The input size.
283      * @return The resulting string.
284      * @throws IOException in case of failure.
285      */
286     @Nonnull public static String toString( @Nonnull final InputStream input )
287         throws IOException
288     {
289         return toString( input, DEFAULT_BUFFER_SIZE );
290     }
291 
292     /**
293      * Get the contents of an <code>InputStream</code> as a String.
294      * The platform's default encoding is used for the byte-to-char conversion.
295      *
296      * @param input The input size.
297      * @param bufferSize Size of internal buffer to use.
298      * @return the resulting string.
299      * @throws IOException in case of failure.
300      */
301     @Nonnull public static String toString( @Nonnull final InputStream input, final int bufferSize )
302         throws IOException
303     {
304         final StringWriter sw = new StringWriter();
305         copy( input, sw, bufferSize );
306         return sw.toString();
307     }
308 
309     /**
310      * Get the contents of an <code>InputStream</code> as a String.
311      *
312      * @param input The input size.
313      * @param encoding The name of a supported character encoding. See the
314      *                 <a href="http://www.iana.org/assignments/character-sets">IANA
315      *                 Charset Registry</a> for a list of valid encoding types.
316      * @return the converted string.
317      * @throws IOException in case of failure.
318      */
319     @Nonnull public static String toString( @Nonnull final InputStream input, @Nonnull final String encoding )
320         throws IOException
321     {
322         return toString( input, encoding, DEFAULT_BUFFER_SIZE );
323     }
324 
325     /**
326      * Get the contents of an <code>InputStream</code> as a String.
327      *
328      * @param input The input size.
329      * @param encoding   The name of a supported character encoding. See the
330      *                   <a href="http://www.iana.org/assignments/character-sets">IANA
331      *                   Charset Registry</a> for a list of valid encoding types.
332      * @param bufferSize Size of internal buffer to use.
333      * @return The converted string.
334      * @throws IOException in case of failure.
335      */
336     @Nonnull public static String toString( @Nonnull final InputStream input, @Nonnull final String encoding,
337                                             final int bufferSize )
338         throws IOException
339     {
340         final StringWriter sw = new StringWriter();
341         copy( input, sw, encoding, bufferSize );
342         return sw.toString();
343     }
344 
345     ///////////////////////////////////////////////////////////////
346     // InputStream -> byte[]
347 
348     /**
349      * Get the contents of an <code>InputStream</code> as a <code>byte[]</code>.
350      * @param input The input size.
351      * @return the resulting byte array.
352      * @throws IOException in case of failure.
353      */
354     @Nonnull public static byte[] toByteArray( @Nonnull final InputStream input )
355         throws IOException
356     {
357         return toByteArray( input, DEFAULT_BUFFER_SIZE );
358     }
359 
360     /**
361      * Get the contents of an <code>InputStream</code> as a <code>byte[]</code>.
362      *
363      * @param input The input size.
364      * @param bufferSize Size of internal buffer to use.
365      * @return the resulting byte array.
366      * @throws IOException in case of failure.
367      */
368     @Nonnull public static byte[] toByteArray( @Nonnull final InputStream input, final int bufferSize )
369         throws IOException
370     {
371         final ByteArrayOutputStream output = new ByteArrayOutputStream();
372         copy( input, output, bufferSize );
373         return output.toByteArray();
374     }
375 
376     ///////////////////////////////////////////////////////////////
377     // Derived copy methods
378     // Reader -> *
379     ///////////////////////////////////////////////////////////////
380 
381     ///////////////////////////////////////////////////////////////
382     // Reader -> OutputStream
383 
384     /**
385      * Serialize chars from a <code>Reader</code> to bytes on an <code>OutputStream</code>, and
386      * flush the <code>OutputStream</code>.
387      * @param input The input size.
388      * @param output The resulting output.
389      * @throws IOException in case of failure.
390      */
391     public static void copy( @Nonnull final Reader input, @Nonnull final OutputStream output )
392         throws IOException
393     {
394         copy( input, output, DEFAULT_BUFFER_SIZE );
395     }
396 
397     /**
398      * Serialize chars from a <code>Reader</code> to bytes on an <code>OutputStream</code>, and
399      * flush the <code>OutputStream</code>.
400      *
401      * @param input The input size.
402      * @param output The resulting output.
403      * @param bufferSize Size of internal buffer to use.
404      * @throws IOException in case of failure.
405      */
406     public static void copy( @Nonnull final Reader input, @Nonnull final OutputStream output, final int bufferSize )
407         throws IOException
408     {
409         final OutputStreamWriter out = new OutputStreamWriter( output );
410         copy( input, out, bufferSize );
411         // NOTE: Unless anyone is planning on rewriting OutputStreamWriter, we have to flush
412         // here.
413         out.flush();
414     }
415 
416     ///////////////////////////////////////////////////////////////
417     // Reader -> String
418 
419     /**
420      * Get the contents of a <code>Reader</code> as a String.
421      * @param input The input size.
422      * @return The converted string.
423      * @throws IOException in case of failure.
424      */
425     @Nonnull public static String toString( @Nonnull final Reader input )
426         throws IOException
427     {
428         return toString( input, DEFAULT_BUFFER_SIZE );
429     }
430 
431     /**
432      * Get the contents of a <code>Reader</code> as a String.
433      *
434      * @param input The input size.
435      * @param bufferSize Size of internal buffer to use.
436      * @return the resulting byte array.
437      * @throws IOException in case of failure.
438      */
439     @Nonnull public static String toString( @Nonnull final Reader input, final int bufferSize )
440         throws IOException
441     {
442         final StringWriter sw = new StringWriter();
443         copy( input, sw, bufferSize );
444         return sw.toString();
445     }
446 
447     ///////////////////////////////////////////////////////////////
448     // Reader -> byte[]
449 
450     /**
451      * Get the contents of a <code>Reader</code> as a <code>byte[]</code>.
452      * @param input The input size.
453      * @return the resulting byte array.
454      * @throws IOException in case of failure.
455      */
456     @Nonnull public static byte[] toByteArray( @Nonnull final Reader input )
457         throws IOException
458     {
459         return toByteArray( input, DEFAULT_BUFFER_SIZE );
460     }
461 
462     /**
463      * Get the contents of a <code>Reader</code> as a <code>byte[]</code>.
464      *
465      * @param input The input size.
466      * @param bufferSize Size of internal buffer to use.
467      * @return the resulting byte array.
468      * @throws IOException in case of failure.
469      */
470     @Nonnull public static byte[] toByteArray( @Nonnull final Reader input, final int bufferSize )
471         throws IOException
472     {
473         ByteArrayOutputStream output = new ByteArrayOutputStream();
474         copy( input, output, bufferSize );
475         return output.toByteArray();
476     }
477 
478     ///////////////////////////////////////////////////////////////
479     // Derived copy methods
480     // String -> *
481     ///////////////////////////////////////////////////////////////
482 
483     ///////////////////////////////////////////////////////////////
484     // String -> OutputStream
485 
486     /**
487      * Serialize chars from a <code>String</code> to bytes on an <code>OutputStream</code>, and
488      * flush the <code>OutputStream</code>.
489      * @param input The input size.
490      * @param output The resulting output.
491      * @throws IOException in case of failure.
492      */
493     public static void copy( @Nonnull final String input, @Nonnull final OutputStream output )
494         throws IOException
495     {
496         copy( input, output, DEFAULT_BUFFER_SIZE );
497     }
498 
499     /**
500      * Serialize chars from a <code>String</code> to bytes on an <code>OutputStream</code>, and
501      * flush the <code>OutputStream</code>.
502      *
503      * @param input The input size.
504      * @param output The resulting output.
505      * @param bufferSize Size of internal buffer to use.
506      * @throws IOException in case of failure.
507      */
508     public static void copy( @Nonnull final String input, @Nonnull final OutputStream output, final int bufferSize )
509         throws IOException
510     {
511         final StringReader in = new StringReader( input );
512         final OutputStreamWriter out = new OutputStreamWriter( output );
513         copy( in, out, bufferSize );
514         // NOTE: Unless anyone is planning on rewriting OutputStreamWriter, we have to flush
515         // here.
516         out.flush();
517     }
518 
519     ///////////////////////////////////////////////////////////////
520     // String -> Writer
521 
522     /**
523      * Copy chars from a <code>String</code> to a <code>Writer</code>.
524      * @param input Input string.
525      * @param output resulting output {@link Writer}
526      * @throws IOException in case of failure.
527      */
528     public static void copy( @Nonnull final String input, @Nonnull final Writer output )
529         throws IOException
530     {
531         output.write( input );
532     }
533 
534     ///////////////////////////////////////////////////////////////
535     // String -> byte[]
536 
537     /**
538      * Get the contents of a <code>String</code> as a <code>byte[]</code>.
539      * @param input The input size.
540      * @return The resulting byte array.
541      * @throws IOException in case of failure.
542      */
543     @Nonnull public static byte[] toByteArray( @Nonnull final String input )
544         throws IOException
545     {
546         return toByteArray( input, DEFAULT_BUFFER_SIZE );
547     }
548 
549     /**
550      * Get the contents of a <code>String</code> as a <code>byte[]</code>.
551      *
552      * @param input The input size.
553      * @param bufferSize Size of internal buffer to use.
554      * @return The resulting byte array.
555      * @throws IOException in case of failure.
556      */
557     @Nonnull public static byte[] toByteArray( @Nonnull final String input, final int bufferSize )
558         throws IOException
559     {
560         ByteArrayOutputStream output = new ByteArrayOutputStream();
561         copy( input, output, bufferSize );
562         return output.toByteArray();
563     }
564 
565     ///////////////////////////////////////////////////////////////
566     // Derived copy methods
567     // byte[] -> *
568     ///////////////////////////////////////////////////////////////
569 
570     ///////////////////////////////////////////////////////////////
571     // byte[] -> Writer
572 
573     /**
574      * Copy and convert bytes from a <code>byte[]</code> to chars on a
575      * <code>Writer</code>.
576      * The platform's default encoding is used for the byte-to-char conversion.
577      * @param input The input size.
578      * @param output The resulting output.
579      * @throws IOException in case of failure.
580      */
581     public static void copy( @Nonnull final byte[] input, @Nonnull 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
589      * <code>Writer</code>.
590      * The platform's default encoding is used for the byte-to-char conversion.
591      *
592      * @param input The input size.
593      * @param output The resulting output.
594      * @param bufferSize Size of internal buffer to use.
595      * @throws IOException in case of failure.
596      */
597     public static void copy( @Nonnull final byte[] input, @Nonnull final Writer output, final int bufferSize )
598         throws IOException
599     {
600         final ByteArrayInputStream in = new ByteArrayInputStream( input );
601         copy( in, output, bufferSize );
602     }
603 
604     /**
605      * Copy and convert bytes from a <code>byte[]</code> to chars on a
606      * <code>Writer</code>, using the specified encoding.
607      *
608      * @param encoding The name of a supported character encoding. See the
609      *                 <a href="http://www.iana.org/assignments/character-sets">IANA
610      *                 Charset Registry</a> for a list of valid encoding types.
611      * @param input The input size.
612      * @param output The resulting output.
613      * @throws IOException in case of failure.
614      */
615     public static void copy( @Nonnull final byte[] input, @Nonnull final Writer output, final String encoding )
616         throws IOException
617     {
618         final ByteArrayInputStream in = new ByteArrayInputStream( input );
619         copy( in, output, encoding );
620     }
621 
622     /**
623      * Copy and convert bytes from a <code>byte[]</code> to chars on a
624      * <code>Writer</code>, using the specified encoding.
625      *
626      * @param encoding   The name of a supported character encoding. See the
627      *                   <a href="http://www.iana.org/assignments/character-sets">IANA
628      *                   Charset Registry</a> for a list of valid encoding types.
629      * @param input The input bytes.
630      * @param output The output buffer {@link Writer}
631      * @param bufferSize Size of internal buffer to use.
632      * @throws IOException in case of failure.
633      */
634     public static void copy( @Nonnull final byte[] input, @Nonnull final Writer output, @Nonnull final String encoding,
635                              final int bufferSize )
636         throws IOException
637     {
638         final ByteArrayInputStream in = new ByteArrayInputStream( input );
639         copy( in, output, encoding, bufferSize );
640     }
641 
642     ///////////////////////////////////////////////////////////////
643     // byte[] -> String
644 
645     /**
646      * Get the contents of a <code>byte[]</code> as a String.
647      * The platform's default encoding is used for the byte-to-char conversion.
648      * @param input The input bytes.
649      * @return The resulting string.
650      * @throws IOException in case of failure.
651      */
652     @Nonnull public static String toString( @Nonnull final byte[] input )
653         throws IOException
654     {
655         return toString( input, DEFAULT_BUFFER_SIZE );
656     }
657 
658     /**
659      * Get the contents of a <code>byte[]</code> as a String.
660      * The platform's default encoding is used for the byte-to-char conversion.
661      *
662      * @param bufferSize Size of internal buffer to use.
663      * @param input The input bytes.
664      * @return The created string.
665      * @throws IOException in case of failure.
666      */
667     @Nonnull public static String toString( @Nonnull final byte[] input, final int bufferSize )
668         throws IOException
669     {
670         final StringWriter sw = new StringWriter();
671         copy( input, sw, bufferSize );
672         return sw.toString();
673     }
674 
675     /**
676      * Get the contents of a <code>byte[]</code> as a String.
677      *
678      * @param encoding The name of a supported character encoding. See the
679      *                 <a href="http://www.iana.org/assignments/character-sets">IANA
680      *                 Charset Registry</a> for a list of valid encoding types.
681      * @param input The input bytes.
682      * @return The resulting string.
683      * @throws IOException in case of failure.
684      */
685     @Nonnull public static String toString( @Nonnull final byte[] input, @Nonnull final String encoding )
686         throws IOException
687     {
688         return toString( input, encoding, DEFAULT_BUFFER_SIZE );
689     }
690 
691     /**
692      * Get the contents of a <code>byte[]</code> as a String.
693      *
694      * @param encoding   The name of a supported character encoding. See the
695      *                   <a href="http://www.iana.org/assignments/character-sets">IANA
696      *                   Charset Registry</a> for a list of valid encoding types.
697      * @param bufferSize Size of internal buffer to use.
698      * @param input Input bytes.
699      * @return The resulting string.
700      * @throws IOException in case of failure.
701      */
702     @Nonnull public static String toString( @Nonnull final byte[] input, @Nonnull final String encoding,
703                                             final int bufferSize )
704         throws IOException
705     {
706         final StringWriter sw = new StringWriter();
707         copy( input, sw, encoding, bufferSize );
708         return sw.toString();
709     }
710 
711     ///////////////////////////////////////////////////////////////
712     // byte[] -> OutputStream
713 
714     /**
715      * Copy bytes from a <code>byte[]</code> to an <code>OutputStream</code>.
716      * @param input Input byte array.
717      * @param output output stream {@link OutputStream}
718      * @throws IOException in case of failure.
719      */
720     public static void copy( @Nonnull final byte[] input, @Nonnull final OutputStream output )
721         throws IOException
722     {
723         output.write( input );
724     }
725 
726     /**
727      * Compare the contents of two Streams to determine if they are equal or not.
728      *
729      * @param input1 the first stream
730      * @param input2 the second stream
731      * @return true if the content of the streams are equal or they both don't exist, false otherwise
732      * @throws IOException in case of failure.
733      */
734     public static boolean contentEquals( @Nonnull final InputStream input1, @Nonnull final InputStream input2 )
735         throws IOException
736     {
737         final InputStream bufferedInput1 = new BufferedInputStream( input1 );
738         final InputStream bufferedInput2 = new BufferedInputStream( input2 );
739 
740         int ch = bufferedInput1.read();
741         while ( -1 != ch )
742         {
743             final int ch2 = bufferedInput2.read();
744             if ( ch != ch2 )
745             {
746                 return false;
747             }
748             ch = bufferedInput1.read();
749         }
750 
751         final int ch2 = bufferedInput2.read();
752         return -1 == ch2;
753     }
754 
755     // ----------------------------------------------------------------------
756     // closeXXX()
757     // ----------------------------------------------------------------------
758 
759     /**
760      * Closes a {@code Channel} suppressing any {@code IOException}.
761      * <p>
762      * <b>Note:</b><br/>The usecase justifying this method is a shortcoming of the Java language up to but not including
763      * Java 7. For any code targetting Java 7 or later use of this method is highly discouraged and the
764      * {@code try-with-resources} statement should be used instead. Care must be taken to not use this method in a way
765      * {@code IOException}s get suppressed incorrectly.
766      * <strong>You must close all resources in use inside the {@code try} block to not suppress exceptions in the
767      * {@code finally} block incorrectly by using this method.</strong>
768      * </p>
769      * <p>
770      * <b>Example:</b><br/>
771      * <pre>
772      * // Introduce variables for the resources and initialize them to null. This cannot throw an exception.
773      * Closeable resource1 = null;
774      * Closeable resource2 = null;
775      * try
776      * {
777      *     // Obtain a resource object and assign it to variable resource1. This may throw an exception.
778      *     // If successful, resource1 != null.
779      *     resource1 = ...
780      *
781      *     // Obtain a resource object and assign it to variable resource2. This may throw an exception.
782      *     // If successful, resource2 != null. Not reached if an exception has been thrown above.
783      *     resource2 = ...
784      *
785      *     // Perform operations on the resources. This may throw an exception. Not reached if an exception has been
786      *     // thrown above. Note: Treat the variables resource1 and resource2 the same way as if they would have been
787      *     // declared with the final modifier - that is - do NOT write anyting like resource1 = something else or
788      *     // resource2 = something else here.
789      *     resource1 ...
790      *     resource2 ...
791      *
792      *     // Finally, close the resources and set the variables to null indicating successful completion.
793      *     // This may throw an exception. Not reached if an exception has been thrown above.
794      *     resource1.close();
795      *     resource1 = null;
796      *     // Not reached if an exception has been thrown above.
797      *     resource2.close();
798      *     resource2 = null;
799      *
800      *     // All resources are closed at this point and all operations (up to here) completed successfully without
801      *     // throwing an exception we would need to handle (by letting it propagate or by catching and handling it).
802      * }
803      * finally
804      * {
805      *     // Cleanup any resource not closed in the try block due to an exception having been thrown and suppress any
806      *     // exception this may produce to not stop the exception from the try block to be propagated. If the try
807      *     // block completed successfully, all variables will have been set to null there and this will not do
808      *     // anything. This is just to cleanup properly in case of an exception.
809      *
810      *     IOUtil.close( resource1 );
811      *     IOUtil.close( resource2 );
812      *
813      *     // Without that utility method you would need to write the following:
814      *     //
815      *     // try
816      *     // {
817      *     //     if ( resource1 != null )
818      *     //     {
819      *     //         resource1.close();
820      *     //     }
821      *     // }
822      *     // catch( IOException e )
823      *     // {
824      *     //     Suppressed. If resource1 != null, an exception has already been thrown in the try block we need to
825      *     //     propagate instead of this one.
826      *     // }
827      *     // finally
828      *     // {
829      *     //     try
830      *     //     {
831      *     //         if ( resource2 != null )
832      *     //         {
833      *     //             resource2.close();
834      *     //         }
835      *     //     }
836      *     //     catch ( IOException e )
837      *     //     {
838      *     //         Suppressed. If resource2 != null, an exception has already been thrown in the try block we need to
839      *     //         propagate instead of this one.
840      *     //     }
841      *     // }
842      * }
843      * </pre>
844      * </p>
845      *
846      * @param channel The channel to close or {@code null}.
847      */
848     public static void close( @Nullable Channel channel )
849     {
850         try
851         {
852             if ( channel != null )
853             {
854                 channel.close();
855             }
856         }
857         catch ( IOException ex )
858         {
859             // Suppressed
860         }
861     }
862 
863     /**
864      * Closes an {@code InputStream} suppressing any {@code IOException}.
865      * <p>
866      * <b>Note:</b><br/>The usecase justifying this method is a shortcoming of the Java language up to but not including
867      * Java 7. For any code targeting Java 7 or later use of this method is highly discouraged and the
868      * {@code try-with-resources} statement should be used instead. Care must be taken to not use this method in a way
869      * {@code IOException}s get suppressed incorrectly.
870      * <strong>You must close all resources in use inside the {@code try} block to not suppress exceptions in the
871      * {@code finally} block incorrectly by using this method.</strong>
872      * </p>
873      * <p>
874      * <b>Example:</b><br/>
875      * <pre>
876      * // Introduce variables for the resources and initialize them to null. This cannot throw an exception.
877      * Closeable resource1 = null;
878      * Closeable resource2 = null;
879      * try
880      * {
881      *     // Obtain a resource object and assign it to variable resource1. This may throw an exception.
882      *     // If successful, resource1 != null.
883      *     resource1 = ...
884      *
885      *     // Obtain a resource object and assign it to variable resource2. This may throw an exception.
886      *     // If successful, resource2 != null. Not reached if an exception has been thrown above.
887      *     resource2 = ...
888      *
889      *     // Perform operations on the resources. This may throw an exception. Not reached if an exception has been
890      *     // thrown above. Note: Treat the variables resource1 and resource2 the same way as if they would have been
891      *     // declared with the final modifier - that is - do NOT write anyting like resource1 = something else or
892      *     // resource2 = something else here.
893      *     resource1 ...
894      *     resource2 ...
895      *
896      *     // Finally, close the resources and set the variables to null indicating successful completion.
897      *     // This may throw an exception. Not reached if an exception has been thrown above.
898      *     resource1.close();
899      *     resource1 = null;
900      *     // This may throw an exception. Not reached if an exception has been thrown above.
901      *     resource2.close();
902      *     resource2 = null;
903      *
904      *     // All resources are closed at this point and all operations (up to here) completed successfully without
905      *     // throwing an exception we would need to handle (by letting it propagate or by catching and handling it).
906      * }
907      * finally
908      * {
909      *     // Cleanup any resource not closed in the try block due to an exception having been thrown and suppress any
910      *     // exception this may produce to not stop the exception from the try block to be propagated. If the try
911      *     // block completed successfully, all variables will have been set to null there and this will not do
912      *     // anything. This is just to cleanup properly in case of an exception.
913      *
914      *     IOUtil.close( resource1 );
915      *     IOUtil.close( resource2 );
916      *
917      *     // Without that utility method you would need to write the following:
918      *     //
919      *     // try
920      *     // {
921      *     //     if ( resource1 != null )
922      *     //     {
923      *     //         resource1.close();
924      *     //     }
925      *     // }
926      *     // catch( IOException e )
927      *     // {
928      *     //     Suppressed. If resource1 != null, an exception has already been thrown in the try block we need to
929      *     //     propagate instead of this one.
930      *     // }
931      *     // finally
932      *     // {
933      *     //     try
934      *     //     {
935      *     //         if ( resource2 != null )
936      *     //         {
937      *     //             resource2.close();
938      *     //         }
939      *     //     }
940      *     //     catch ( IOException e )
941      *     //     {
942      *     //         Suppressed. If resource2 != null, an exception has already been thrown in the try block we need to
943      *     //         propagate instead of this one.
944      *     //     }
945      *     // }
946      * }
947      * </pre>
948      * </p>
949      *
950      * @param inputStream The stream to close or {@code null}.
951      */
952     public static void close( @Nullable InputStream inputStream )
953     {
954         try
955         {
956             if ( inputStream != null )
957             {
958                 inputStream.close();
959             }
960         }
961         catch ( IOException ex )
962         {
963             // Suppressed
964         }
965     }
966 
967     /**
968      * Closes an {@code OutputStream} suppressing any {@code IOException}.
969      * <p>
970      * <b>Note:</b><br/>The usecase justifying this method is a shortcoming of the Java language up to but not including
971      * Java 7. For any code targeting Java 7 or later use of this method is highly discouraged and the
972      * {@code try-with-resources} statement should be used instead. Care must be taken to not use this method in a way
973      * {@code IOException}s get suppressed incorrectly.
974      * <strong>You must close all resources in use inside the {@code try} block to not suppress exceptions in the
975      * {@code finally} block incorrectly by using this method.</strong>
976      * </p>
977      * <p>
978      * <b>Example:</b><br/>
979      * <pre>
980      * // Introduce variables for the resources and initialize them to null. This cannot throw an exception.
981      * Closeable resource1 = null;
982      * Closeable resource2 = null;
983      * try
984      * {
985      *     // Obtain a resource object and assign it to variable resource1. This may throw an exception.
986      *     // If successful, resource1 != null.
987      *     resource1 = ...
988      *
989      *     // Obtain a resource object and assign it to variable resource2. This may throw an exception.
990      *     // If successful, resource2 != null. Not reached if an exception has been thrown above.
991      *     resource2 = ...
992      *
993      *     // Perform operations on the resources. This may throw an exception. Not reached if an exception has been
994      *     // thrown above. Note: Treat the variables resource1 and resource2 the same way as if they would have been
995      *     // declared with the final modifier - that is - do NOT write anyting like resource1 = something else or
996      *     // resource2 = something else here.
997      *     resource1 ...
998      *     resource2 ...
999      *
1000      *     // Finally, close the resources and set the variables to null indicating successful completion.
1001      *     // This may throw an exception. Not reached if an exception has been thrown above.
1002      *     resource1.close();
1003      *     resource1 = null;
1004      *     // This may throw an exception. Not reached if an exception has been thrown above.
1005      *     resource2.close();
1006      *     resource2 = null;
1007      *
1008      *     // All resources are closed at this point and all operations (up to here) completed successfully without
1009      *     // throwing an exception we would need to handle (by letting it propagate or by catching and handling it).
1010      * }
1011      * finally
1012      * {
1013      *     // Cleanup any resource not closed in the try block due to an exception having been thrown and suppress any
1014      *     // exception this may produce to not stop the exception from the try block to be propagated. If the try
1015      *     // block completed successfully, all variables will have been set to null there and this will not do
1016      *     // anything. This is just to cleanup properly in case of an exception.
1017      *
1018      *     IOUtil.close( resource1 );
1019      *     IOUtil.close( resource2 );
1020      *
1021      *     // Without that utility method you would need to write the following:
1022      *     //
1023      *     // try
1024      *     // {
1025      *     //     if ( resource1 != null )
1026      *     //     {
1027      *     //         resource1.close();
1028      *     //     }
1029      *     // }
1030      *     // catch( IOException e )
1031      *     // {
1032      *     //     Suppressed. If resource1 != null, an exception has already been thrown in the try block we need to
1033      *     //     propagate instead of this one.
1034      *     // }
1035      *     // finally
1036      *     // {
1037      *     //     try
1038      *     //     {
1039      *     //         if ( resource2 != null )
1040      *     //         {
1041      *     //             resource2.close();
1042      *     //         }
1043      *     //     }
1044      *     //     catch ( IOException e )
1045      *     //     {
1046      *     //         Suppressed. If resource2 != null, an exception has already been thrown in the try block we need to
1047      *     //         propagate instead of this one.
1048      *     //     }
1049      *     // }
1050      * }
1051      * </pre>
1052      * </p>
1053      *
1054      * @param outputStream The stream to close or {@code null}.
1055      */
1056     public static void close( @Nullable OutputStream outputStream )
1057     {
1058         try
1059         {
1060             if ( outputStream != null )
1061             {
1062                 outputStream.close();
1063             }
1064         }
1065         catch ( IOException ex )
1066         {
1067             // Suppressed
1068         }
1069     }
1070 
1071     /**
1072      * Closes a {@code Reader} suppressing any {@code IOException}.
1073      * <p>
1074      * <b>Note:</b><br/>The usecase justifying this method is a shortcoming of the Java language up to but not including
1075      * Java 7. For any code targeting Java 7 or later use of this method is highly discouraged and the
1076      * {@code try-with-resources} statement should be used instead. Care must be taken to not use this method in a way
1077      * {@code IOException}s get suppressed incorrectly.
1078      * <strong>You must close all resources in use inside the {@code try} block to not suppress exceptions in the
1079      * {@code finally} block incorrectly by using this method.</strong>
1080      * </p>
1081      * <p>
1082      * <b>Example:</b><br/>
1083      * <pre>
1084      * // Introduce variables for the resources and initialize them to null. This cannot throw an exception.
1085      * Closeable resource1 = null;
1086      * Closeable resource2 = null;
1087      * try
1088      * {
1089      *     // Obtain a resource object and assign it to variable resource1. This may throw an exception.
1090      *     // If successful, resource1 != null.
1091      *     resource1 = ...
1092      *
1093      *     // Obtain a resource object and assign it to variable resource2. This may throw an exception.
1094      *     // If successful, resource2 != null. Not reached if an exception has been thrown above.
1095      *     resource2 = ...
1096      *
1097      *     // Perform operations on the resources. This may throw an exception. Not reached if an exception has been
1098      *     // thrown above. Note: Treat the variables resource1 and resource2 the same way as if they would have been
1099      *     // declared with the final modifier - that is - do NOT write anyting like resource1 = something else or
1100      *     // resource2 = something else here.
1101      *     resource1 ...
1102      *     resource2 ...
1103      *
1104      *     // Finally, close the resources and set the variables to null indicating successful completion.
1105      *     // This may throw an exception. Not reached if an exception has been thrown above.
1106      *     resource1.close();
1107      *     resource1 = null;
1108      *     // This may throw an exception. Not reached if an exception has been thrown above.
1109      *     resource2.close();
1110      *     resource2 = null;
1111      *
1112      *     // All resources are closed at this point and all operations (up to here) completed successfully without
1113      *     // throwing an exception we would need to handle (by letting it propagate or by catching and handling it).
1114      * }
1115      * finally
1116      * {
1117      *     // Cleanup any resource not closed in the try block due to an exception having been thrown and suppress any
1118      *     // exception this may produce to not stop the exception from the try block to be propagated. If the try
1119      *     // block completed successfully, all variables will have been set to null there and this will not do
1120      *     // anything. This is just to cleanup properly in case of an exception.
1121      *
1122      *     IOUtil.close( resource1 );
1123      *     IOUtil.close( resource2 );
1124      *
1125      *     // Without that utility method you would need to write the following:
1126      *     //
1127      *     // try
1128      *     // {
1129      *     //     if ( resource1 != null )
1130      *     //     {
1131      *     //         resource1.close();
1132      *     //     }
1133      *     // }
1134      *     // catch( IOException e )
1135      *     // {
1136      *     //     Suppressed. If resource1 != null, an exception has already been thrown in the try block we need to
1137      *     //     propagate instead of this one.
1138      *     // }
1139      *     // finally
1140      *     // {
1141      *     //     try
1142      *     //     {
1143      *     //         if ( resource2 != null )
1144      *     //         {
1145      *     //             resource2.close();
1146      *     //         }
1147      *     //     }
1148      *     //     catch ( IOException e )
1149      *     //     {
1150      *     //         Suppressed. If resource2 != null, an exception has already been thrown in the try block we need to
1151      *     //         propagate instead of this one.
1152      *     //     }
1153      *     // }
1154      * }
1155      * </pre>
1156      * </p>
1157      *
1158      * @param reader The reader to close or {@code null}.
1159      */
1160     public static void close( @Nullable Reader reader )
1161     {
1162         try
1163         {
1164             if ( reader != null )
1165             {
1166                 reader.close();
1167             }
1168         }
1169         catch ( IOException ex )
1170         {
1171             // Suppressed
1172         }
1173     }
1174 
1175     /**
1176      * Closes a {@code Writer} suppressing any {@code IOException}.
1177      * <p>
1178      * <b>Note:</b><br/>The usecase justifying this method is a shortcoming of the Java language up to but not including
1179      * Java 7. For any code targeting Java 7 or later use of this method is highly discouraged and the
1180      * {@code try-with-resources} statement should be used instead. Care must be taken to not use this method in a way
1181      * {@code IOException}s get suppressed incorrectly.
1182      * <strong>You must close all resources in use inside the {@code try} block to not suppress exceptions in the
1183      * {@code finally} block incorrectly by using this method.</strong>
1184      * </p>
1185      * <p>
1186      * <b>Example:</b><br/>
1187      * <pre>
1188      * // Introduce variables for the resources and initialize them to null. This cannot throw an exception.
1189      * Closeable resource1 = null;
1190      * Closeable resource2 = null;
1191      * try
1192      * {
1193      *     // Obtain a resource object and assign it to variable resource1. This may throw an exception.
1194      *     // If successful, resource1 != null.
1195      *     resource1 = ...
1196      *
1197      *     // Obtain a resource object and assign it to variable resource2. This may throw an exception.
1198      *     // If successful, resource2 != null. Not reached if an exception has been thrown above.
1199      *     resource2 = ...
1200      *
1201      *     // Perform operations on the resources. This may throw an exception. Not reached if an exception has been
1202      *     // thrown above. Note: Treat the variables resource1 and resource2 the same way as if they would have been
1203      *     // declared with the final modifier - that is - do NOT write anyting like resource1 = something else or
1204      *     // resource2 = something else here.
1205      *     resource1 ...
1206      *     resource2 ...
1207      *
1208      *     // Finally, close the resources and set the variables to null indicating successful completion.
1209      *     // This may throw an exception. Not reached if an exception has been thrown above.
1210      *     resource1.close();
1211      *     resource1 = null;
1212      *     // This may throw an exception. Not reached if an exception has been thrown above.
1213      *     resource2.close();
1214      *     resource2 = null;
1215      *
1216      *     // All resources are closed at this point and all operations (up to here) completed successfully without
1217      *     // throwing an exception we would need to handle (by letting it propagate or by catching and handling it).
1218      * }
1219      * finally
1220      * {
1221      *     // Cleanup any resource not closed in the try block due to an exception having been thrown and suppress any
1222      *     // exception this may produce to not stop the exception from the try block to be propagated. If the try
1223      *     // block completed successfully, all variables will have been set to null there and this will not do
1224      *     // anything. This is just to cleanup properly in case of an exception.
1225      *
1226      *     IOUtil.close( resource1 );
1227      *     IOUtil.close( resource2 );
1228      *
1229      *     // Without that utility method you would need to write the following:
1230      *     //
1231      *     // try
1232      *     // {
1233      *     //     if ( resource1 != null )
1234      *     //     {
1235      *     //         resource1.close();
1236      *     //     }
1237      *     // }
1238      *     // catch( IOException e )
1239      *     // {
1240      *     //     Suppressed. If resource1 != null, an exception has already been thrown in the try block we need to
1241      *     //     propagate instead of this one.
1242      *     // }
1243      *     // finally
1244      *     // {
1245      *     //     try
1246      *     //     {
1247      *     //         if ( resource2 != null )
1248      *     //         {
1249      *     //             resource2.close();
1250      *     //         }
1251      *     //     }
1252      *     //     catch ( IOException e )
1253      *     //     {
1254      *     //         Suppressed. If resource2 != null, an exception has already been thrown in the try block we need to
1255      *     //         propagate instead of this one.
1256      *     //     }
1257      *     // }
1258      * }
1259      * </pre>
1260      * </p>
1261      *
1262      * @param writer The writer to close or {@code null}.
1263      */
1264     public static void close( @Nullable Writer writer )
1265     {
1266         try
1267         {
1268             if ( writer != null )
1269             {
1270                 writer.close();
1271             }
1272         }
1273         catch ( IOException ex )
1274         {
1275             // Suppressed
1276         }
1277     }
1278 }