View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.io;
18  
19  import java.io.BufferedInputStream;
20  import java.io.BufferedOutputStream;
21  import java.io.BufferedReader;
22  import java.io.BufferedWriter;
23  import java.io.ByteArrayInputStream;
24  import java.io.CharArrayWriter;
25  import java.io.Closeable;
26  import java.io.EOFException;
27  import java.io.File;
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.PrintWriter;
34  import java.io.Reader;
35  import java.io.UnsupportedEncodingException;
36  import java.io.Writer;
37  import java.net.HttpURLConnection;
38  import java.net.ServerSocket;
39  import java.net.Socket;
40  import java.net.URI;
41  import java.net.URL;
42  import java.net.URLConnection;
43  import java.nio.ByteBuffer;
44  import java.nio.channels.ReadableByteChannel;
45  import java.nio.channels.Selector;
46  import java.nio.charset.Charset;
47  import java.nio.charset.UnsupportedCharsetException;
48  import java.util.ArrayList;
49  import java.util.Collection;
50  import java.util.List;
51  
52  import org.apache.commons.io.output.ByteArrayOutputStream;
53  import org.apache.commons.io.output.StringBuilderWriter;
54  
55  /**
56   * General IO stream manipulation utilities.
57   * <p>
58   * This class provides static utility methods for input/output operations.
59   * <ul>
60   * <li>closeQuietly - these methods close a stream ignoring nulls and exceptions
61   * <li>toXxx/read - these methods read data from a stream
62   * <li>write - these methods write data to a stream
63   * <li>copy - these methods copy all the data from one stream to another
64   * <li>contentEquals - these methods compare the content of two streams
65   * </ul>
66   * <p>
67   * The byte-to-char methods and char-to-byte methods involve a conversion step.
68   * Two methods are provided in each case, one that uses the platform default
69   * encoding and the other which allows you to specify an encoding. You are
70   * encouraged to always specify an encoding because relying on the platform
71   * default can lead to unexpected results, for example when moving from
72   * development to production.
73   * <p>
74   * All the methods in this class that read a stream are buffered internally.
75   * This means that there is no cause to use a <code>BufferedInputStream</code>
76   * or <code>BufferedReader</code>. The default buffer size of 4K has been shown
77   * to be efficient in tests.
78   * <p>
79   * Wherever possible, the methods in this class do <em>not</em> flush or close
80   * the stream. This is to avoid making non-portable assumptions about the
81   * streams' origin and further use. Thus the caller is still responsible for
82   * closing streams after use.
83   * <p>
84   * Origin of code: Excalibur.
85   *
86   * @version $Id: IOUtils.java 1471767 2013-04-24 23:24:19Z sebb $
87   */
88  public class IOUtils {
89      // NOTE: This class is focussed on InputStream, OutputStream, Reader and
90      // Writer. Each method should take at least one of these as a parameter,
91      // or return one of them.
92  
93      private static final int EOF = -1;
94      /**
95       * The Unix directory separator character.
96       */
97      public static final char DIR_SEPARATOR_UNIX = '/';
98      /**
99       * The Windows directory separator character.
100      */
101     public static final char DIR_SEPARATOR_WINDOWS = '\\';
102     /**
103      * The system directory separator character.
104      */
105     public static final char DIR_SEPARATOR = File.separatorChar;
106     /**
107      * The Unix line separator string.
108      */
109     public static final String LINE_SEPARATOR_UNIX = "\n";
110     /**
111      * The Windows line separator string.
112      */
113     public static final String LINE_SEPARATOR_WINDOWS = "\r\n";
114     /**
115      * The system line separator string.
116      */
117     public static final String LINE_SEPARATOR;
118 
119     static {
120         // avoid security issues
121         final StringBuilderWriter buf = new StringBuilderWriter(4);
122         final PrintWriter out = new PrintWriter(buf);
123         out.println();
124         LINE_SEPARATOR = buf.toString();
125         out.close();
126     }
127 
128     /**
129      * The default buffer size ({@value}) to use for
130      * {@link #copyLarge(InputStream, OutputStream)}
131      * and
132      * {@link #copyLarge(Reader, Writer)}
133      */
134     private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
135 
136     /**
137      * The default buffer size to use for the skip() methods.
138      */
139     private static final int SKIP_BUFFER_SIZE = 2048;
140 
141     // Allocated in the relevant skip method if necessary.
142     /*
143      * N.B. no need to synchronize these because:
144      * - we don't care if the buffer is created multiple times (the data is ignored)
145      * - we always use the same size buffer, so if it it is recreated it will still be OK
146      * (if the buffer size were variable, we would need to synch. to ensure some other thread
147      * did not create a smaller one)
148      */
149     private static char[] SKIP_CHAR_BUFFER;
150     private static byte[] SKIP_BYTE_BUFFER;
151 
152     /**
153      * Instances should NOT be constructed in standard programming.
154      */
155     public IOUtils() {
156         super();
157     }
158 
159     //-----------------------------------------------------------------------
160 
161     /**
162      * Closes a URLConnection.
163      *
164      * @param conn the connection to close.
165      * @since 2.4
166      */
167     public static void close(final URLConnection conn) {
168         if (conn instanceof HttpURLConnection) {
169             ((HttpURLConnection) conn).disconnect();
170         }
171     }
172 
173     /**
174      * Closes an <code>Reader</code> unconditionally.
175      * <p>
176      * Equivalent to {@link Reader#close()}, except any exceptions will be ignored.
177      * This is typically used in finally blocks.
178      * <p>
179      * Example code:
180      * <pre>
181      *   char[] data = new char[1024];
182      *   Reader in = null;
183      *   try {
184      *       in = new FileReader("foo.txt");
185      *       in.read(data);
186      *       in.close(); //close errors are handled
187      *   } catch (Exception e) {
188      *       // error handling
189      *   } finally {
190      *       IOUtils.closeQuietly(in);
191      *   }
192      * </pre>
193      *
194      * @param input  the Reader to close, may be null or already closed
195      */
196     public static void closeQuietly(final Reader input) {
197         closeQuietly((Closeable)input);
198     }
199 
200     /**
201      * Closes an <code>Writer</code> unconditionally.
202      * <p>
203      * Equivalent to {@link Writer#close()}, except any exceptions will be ignored.
204      * This is typically used in finally blocks.
205      * <p>
206      * Example code:
207      * <pre>
208      *   Writer out = null;
209      *   try {
210      *       out = new StringWriter();
211      *       out.write("Hello World");
212      *       out.close(); //close errors are handled
213      *   } catch (Exception e) {
214      *       // error handling
215      *   } finally {
216      *       IOUtils.closeQuietly(out);
217      *   }
218      * </pre>
219      *
220      * @param output  the Writer to close, may be null or already closed
221      */
222     public static void closeQuietly(final Writer output) {
223         closeQuietly((Closeable)output);
224     }
225 
226     /**
227      * Closes an <code>InputStream</code> unconditionally.
228      * <p>
229      * Equivalent to {@link InputStream#close()}, except any exceptions will be ignored.
230      * This is typically used in finally blocks.
231      * <p>
232      * Example code:
233      * <pre>
234      *   byte[] data = new byte[1024];
235      *   InputStream in = null;
236      *   try {
237      *       in = new FileInputStream("foo.txt");
238      *       in.read(data);
239      *       in.close(); //close errors are handled
240      *   } catch (Exception e) {
241      *       // error handling
242      *   } finally {
243      *       IOUtils.closeQuietly(in);
244      *   }
245      * </pre>
246      *
247      * @param input  the InputStream to close, may be null or already closed
248      */
249     public static void closeQuietly(final InputStream input) {
250         closeQuietly((Closeable)input);
251     }
252 
253     /**
254      * Closes an <code>OutputStream</code> unconditionally.
255      * <p>
256      * Equivalent to {@link OutputStream#close()}, except any exceptions will be ignored.
257      * This is typically used in finally blocks.
258      * <p>
259      * Example code:
260      * <pre>
261      * byte[] data = "Hello, World".getBytes();
262      *
263      * OutputStream out = null;
264      * try {
265      *     out = new FileOutputStream("foo.txt");
266      *     out.write(data);
267      *     out.close(); //close errors are handled
268      * } catch (IOException e) {
269      *     // error handling
270      * } finally {
271      *     IOUtils.closeQuietly(out);
272      * }
273      * </pre>
274      *
275      * @param output  the OutputStream to close, may be null or already closed
276      */
277     public static void closeQuietly(final OutputStream output) {
278         closeQuietly((Closeable)output);
279     }
280 
281     /**
282      * Closes a <code>Closeable</code> unconditionally.
283      * <p>
284      * Equivalent to {@link Closeable#close()}, except any exceptions will be ignored.
285      * This is typically used in finally blocks.
286      * <p>
287      * Example code:
288      * <pre>
289      *   Closeable closeable = null;
290      *   try {
291      *       closeable = new FileReader("foo.txt");
292      *       // process closeable
293      *       closeable.close();
294      *   } catch (Exception e) {
295      *       // error handling
296      *   } finally {
297      *       IOUtils.closeQuietly(closeable);
298      *   }
299      * </pre>
300      *
301      * @param closeable the object to close, may be null or already closed
302      * @since 2.0
303      */
304     public static void closeQuietly(final Closeable closeable) {
305         try {
306             if (closeable != null) {
307                 closeable.close();
308             }
309         } catch (final IOException ioe) {
310             // ignore
311         }
312     }
313 
314     /**
315      * Closes a <code>Socket</code> unconditionally.
316      * <p>
317      * Equivalent to {@link Socket#close()}, except any exceptions will be ignored.
318      * This is typically used in finally blocks.
319      * <p>
320      * Example code:
321      * <pre>
322      *   Socket socket = null;
323      *   try {
324      *       socket = new Socket("http://www.foo.com/", 80);
325      *       // process socket
326      *       socket.close();
327      *   } catch (Exception e) {
328      *       // error handling
329      *   } finally {
330      *       IOUtils.closeQuietly(socket);
331      *   }
332      * </pre>
333      *
334      * @param sock the Socket to close, may be null or already closed
335      * @since 2.0
336      */
337     public static void closeQuietly(final Socket sock){
338         if (sock != null){
339             try {
340                 sock.close();
341             } catch (final IOException ioe) {
342                 // ignored
343             }
344         }
345     }
346 
347     /**
348      * Closes a <code>Selector</code> unconditionally.
349      * <p>
350      * Equivalent to {@link Selector#close()}, except any exceptions will be ignored.
351      * This is typically used in finally blocks.
352      * <p>
353      * Example code:
354      * <pre>
355      *   Selector selector = null;
356      *   try {
357      *       selector = Selector.open();
358      *       // process socket
359      *
360      *   } catch (Exception e) {
361      *       // error handling
362      *   } finally {
363      *       IOUtils.closeQuietly(selector);
364      *   }
365      * </pre>
366      *
367      * @param selector the Selector to close, may be null or already closed
368      * @since 2.2
369      */
370     public static void closeQuietly(final Selector selector){
371         if (selector != null){
372             try {
373               selector.close();
374             } catch (final IOException ioe) {
375                 // ignored
376             }
377         }
378     }
379 
380     /**
381      * Closes a <code>ServerSocket</code> unconditionally.
382      * <p>
383      * Equivalent to {@link ServerSocket#close()}, except any exceptions will be ignored.
384      * This is typically used in finally blocks.
385      * <p>
386      * Example code:
387      * <pre>
388      *   ServerSocket socket = null;
389      *   try {
390      *       socket = new ServerSocket();
391      *       // process socket
392      *       socket.close();
393      *   } catch (Exception e) {
394      *       // error handling
395      *   } finally {
396      *       IOUtils.closeQuietly(socket);
397      *   }
398      * </pre>
399      *
400      * @param sock the ServerSocket to close, may be null or already closed
401      * @since 2.2
402      */
403     public static void closeQuietly(final ServerSocket sock){
404         if (sock != null){
405             try {
406                 sock.close();
407             } catch (final IOException ioe) {
408                 // ignored
409             }
410         }
411     }
412 
413     /**
414      * Fetches entire contents of an <code>InputStream</code> and represent
415      * same data as result InputStream.
416      * <p>
417      * This method is useful where,
418      * <ul>
419      * <li>Source InputStream is slow.</li>
420      * <li>It has network resources associated, so we cannot keep it open for
421      * long time.</li>
422      * <li>It has network timeout associated.</li>
423      * </ul>
424      * It can be used in favor of {@link #toByteArray(InputStream)}, since it
425      * avoids unnecessary allocation and copy of byte[].<br>
426      * This method buffers the input internally, so there is no need to use a
427      * <code>BufferedInputStream</code>.
428      *
429      * @param input Stream to be fully buffered.
430      * @return A fully buffered stream.
431      * @throws IOException if an I/O error occurs
432      * @since 2.0
433      */
434     public static InputStream toBufferedInputStream(final InputStream input) throws IOException {
435         return ByteArrayOutputStream.toBufferedInputStream(input);
436     }
437 
438     /**
439      * Returns the given reader if it is a {@link BufferedReader}, otherwise creates a BufferedReader from the given
440      * reader.
441      *
442      * @param reader
443      *            the reader to wrap or return (not null)
444      * @return the given reader or a new {@link BufferedReader} for the given reader
445      * @since 2.2
446      * @see #asBufferedReader(Reader)
447      * @throws NullPointerException if the input parameter is null
448      */
449     public static BufferedReader toBufferedReader(final Reader reader) {
450         return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader);
451     }
452 
453     /**
454      * Returns the given reader if it is already a {@link BufferedReader}, otherwise creates a BufferedReader from the given
455      * reader.
456      *
457      * @param reader
458      *            the reader to wrap or return (not null)
459      * @return the given reader or a new {@link BufferedReader} for the given reader
460      * @since 2.5
461      * @throws NullPointerException if the input parameter is null
462      */
463     public static BufferedReader asBufferedReader(final Reader reader) {
464         return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader);
465     }
466 
467     /**
468      * Returns the given Writer if it is already a {@link BufferedWriter}, otherwise creates a BufferedWriter from the given
469      * Writer.
470      *
471      * @param writer
472      *            the Writer to wrap or return (not null)
473      * @return the given Writer or a new {@link BufferedWriter} for the given Writer
474      * @since 2.5
475      * @throws NullPointerException if the input parameter is null
476      */
477     public static BufferedWriter asBufferedWriter(final Writer writer) {
478         return writer instanceof BufferedWriter ? (BufferedWriter) writer : new BufferedWriter(writer);
479     }
480 
481     /**
482      * Returns the given OutputStream if it is already a {@link BufferedOutputStream}, otherwise creates a BufferedOutputStream from the given
483      * OutputStream.
484      *
485      * @param outputStream
486      *            the OutputStream to wrap or return (not null)
487      * @return the given OutputStream or a new {@link BufferedOutputStream} for the given OutputStream
488      * @since 2.5
489      * @throws NullPointerException if the input parameter is null
490      */
491     public static BufferedOutputStream asBufferedOutputStream(final OutputStream outputStream) {
492         // reject null early on rather than waiting for IO operation to fail
493         if (outputStream == null) { // not checked by BufferedOutputStream
494             throw new NullPointerException();
495         }
496         return outputStream instanceof BufferedOutputStream ? (BufferedOutputStream) outputStream : new BufferedOutputStream(outputStream);
497     }
498 
499     /**
500      * Returns the given InputStream if it is already a {@link BufferedInputStream}, otherwise creates a BufferedInputStream from the given
501      * InputStream.
502      *
503      * @param inputStream
504      *            the InputStream to wrap or return (not null)
505      * @return the given InputStream or a new {@link BufferedInputStream} for the given InputStream
506      * @since 2.5
507      * @throws NullPointerException if the input parameter is null
508      */
509     public static BufferedInputStream asBufferedInputStream(final InputStream inputStream) {
510         // reject null early on rather than waiting for IO operation to fail
511         if (inputStream == null) { // not checked by BufferedInputStream
512             throw new NullPointerException();
513         }
514         return inputStream instanceof BufferedInputStream ? (BufferedInputStream) inputStream : new BufferedInputStream(inputStream);
515     }
516 
517     // read toByteArray
518     //-----------------------------------------------------------------------
519     /**
520      * Gets the contents of an <code>InputStream</code> as a <code>byte[]</code>.
521      * <p>
522      * This method buffers the input internally, so there is no need to use a
523      * <code>BufferedInputStream</code>.
524      *
525      * @param input  the <code>InputStream</code> to read from
526      * @return the requested byte array
527      * @throws NullPointerException if the input is null
528      * @throws IOException if an I/O error occurs
529      */
530     public static byte[] toByteArray(final InputStream input) throws IOException {
531         final ByteArrayOutputStream output = new ByteArrayOutputStream();
532         copy(input, output);
533         return output.toByteArray();
534     }
535 
536     /**
537      * Gets contents of an <code>InputStream</code> as a <code>byte[]</code>.
538      * Use this method instead of <code>toByteArray(InputStream)</code>
539      * when <code>InputStream</code> size is known.
540      * <b>NOTE:</b> the method checks that the length can safely be cast to an int without truncation
541      * before using {@link IOUtils#toByteArray(java.io.InputStream, int)} to read into the byte array.
542      * (Arrays can have no more than Integer.MAX_VALUE entries anyway)
543      *
544      * @param input the <code>InputStream</code> to read from
545      * @param size the size of <code>InputStream</code>
546      * @return the requested byte array
547      * @throws IOException if an I/O error occurs or <code>InputStream</code> size differ from parameter size
548      * @throws IllegalArgumentException if size is less than zero or size is greater than Integer.MAX_VALUE
549      * @see IOUtils#toByteArray(java.io.InputStream, int)
550      * @since 2.1
551      */
552     public static byte[] toByteArray(final InputStream input, final long size) throws IOException {
553 
554       if(size > Integer.MAX_VALUE) {
555           throw new IllegalArgumentException("Size cannot be greater than Integer max value: " + size);
556       }
557 
558       return toByteArray(input, (int) size);
559     }
560 
561     /**
562      * Gets the contents of an <code>InputStream</code> as a <code>byte[]</code>.
563      * Use this method instead of <code>toByteArray(InputStream)</code>
564      * when <code>InputStream</code> size is known
565      * @param input the <code>InputStream</code> to read from
566      * @param size the size of <code>InputStream</code>
567      * @return the requested byte array
568      * @throws IOException if an I/O error occurs or <code>InputStream</code> size differ from parameter size
569      * @throws IllegalArgumentException if size is less than zero
570      * @since 2.1
571      */
572     public static byte[] toByteArray(final InputStream input, final int size) throws IOException {
573 
574         if (size < 0) {
575             throw new IllegalArgumentException("Size must be equal or greater than zero: " + size);
576         }
577 
578         if (size == 0) {
579             return new byte[0];
580         }
581 
582         final byte[] data = new byte[size];
583         int offset = 0;
584         int readed;
585 
586         while (offset < size && (readed = input.read(data, offset, size - offset)) != EOF) {
587             offset += readed;
588         }
589 
590         if (offset != size) {
591             throw new IOException("Unexpected readed size. current: " + offset + ", excepted: " + size);
592         }
593 
594         return data;
595     }
596 
597     /**
598      * Gets the contents of a <code>Reader</code> as a <code>byte[]</code>
599      * using the default character encoding of the platform.
600      * <p>
601      * This method buffers the input internally, so there is no need to use a
602      * <code>BufferedReader</code>.
603      *
604      * @param input  the <code>Reader</code> to read from
605      * @return the requested byte array
606      * @throws NullPointerException if the input is null
607      * @throws IOException if an I/O error occurs
608      * @deprecated 2.5 use {@link #toByteArray(Reader, Charset)} instead
609      */
610     @Deprecated
611     public static byte[] toByteArray(final Reader input) throws IOException {
612         return toByteArray(input, Charset.defaultCharset());
613     }
614 
615     /**
616      * Gets the contents of a <code>Reader</code> as a <code>byte[]</code>
617      * using the specified character encoding.
618      * <p>
619      * This method buffers the input internally, so there is no need to use a
620      * <code>BufferedReader</code>.
621      *
622      * @param input  the <code>Reader</code> to read from
623      * @param encoding  the encoding to use, null means platform default
624      * @return the requested byte array
625      * @throws NullPointerException if the input is null
626      * @throws IOException if an I/O error occurs
627      * @since 2.3
628      */
629     public static byte[] toByteArray(final Reader input, final Charset encoding) throws IOException {
630         final ByteArrayOutputStream output = new ByteArrayOutputStream();
631         copy(input, output, encoding);
632         return output.toByteArray();
633     }
634 
635     /**
636      * Gets the contents of a <code>Reader</code> as a <code>byte[]</code>
637      * using the specified character encoding.
638      * <p>
639      * Character encoding names can be found at
640      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
641      * <p>
642      * This method buffers the input internally, so there is no need to use a
643      * <code>BufferedReader</code>.
644      *
645      * @param input  the <code>Reader</code> to read from
646      * @param encoding  the encoding to use, null means platform default
647      * @return the requested byte array
648      * @throws NullPointerException if the input is null
649      * @throws IOException if an I/O error occurs
650      * @throws UnsupportedCharsetException
651      *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
652      *             supported.
653      * @since 1.1
654      */
655     public static byte[] toByteArray(final Reader input, final String encoding) throws IOException {
656         return toByteArray(input, Charsets.toCharset(encoding));
657     }
658 
659     /**
660      * Gets the contents of a <code>String</code> as a <code>byte[]</code>
661      * using the default character encoding of the platform.
662      * <p>
663      * This is the same as {@link String#getBytes()}.
664      *
665      * @param input  the <code>String</code> to convert
666      * @return the requested byte array
667      * @throws NullPointerException if the input is null
668      * @throws IOException if an I/O error occurs (never occurs)
669      * @deprecated 2.5 Use {@link String#getBytes()} instead
670      */
671     @Deprecated
672     public static byte[] toByteArray(final String input) throws IOException {
673         // make explicit the use of the default charset
674         return input.getBytes(Charset.defaultCharset());
675     }
676 
677     /**
678      * Gets the contents of a <code>URI</code> as a <code>byte[]</code>.
679      *
680      * @param uri
681      *            the <code>URI</code> to read
682      * @return the requested byte array
683      * @throws NullPointerException
684      *             if the uri is null
685      * @throws IOException
686      *             if an I/O exception occurs
687      * @since 2.4
688      */
689     public static byte[] toByteArray(final URI uri) throws IOException {
690         return IOUtils.toByteArray(uri.toURL());
691     }
692 
693     /**
694      * Gets the contents of a <code>URL</code> as a <code>byte[]</code>.
695      *
696      * @param url
697      *            the <code>URL</code> to read
698      * @return the requested byte array
699      * @throws NullPointerException
700      *             if the input is null
701      * @throws IOException
702      *             if an I/O exception occurs
703      * @since 2.4
704      */
705     public static byte[] toByteArray(final URL url) throws IOException {
706         final URLConnection conn = url.openConnection();
707         try {
708             return IOUtils.toByteArray(conn);
709         } finally {
710             close(conn);
711         }
712     }
713 
714     /**
715      * Gets the contents of a <code>URLConnection</code> as a <code>byte[]</code>.
716      *
717      * @param urlConn
718      *            the <code>URLConnection</code> to read
719      * @return the requested byte array
720      * @throws NullPointerException
721      *             if the urlConn is null
722      * @throws IOException
723      *             if an I/O exception occurs
724      * @since 2.4
725      */
726     public static byte[] toByteArray(final URLConnection urlConn) throws IOException {
727         final InputStream inputStream = urlConn.getInputStream();
728         try {
729             return IOUtils.toByteArray(inputStream);
730         } finally {
731             inputStream.close();
732         }
733     }
734 
735     // read char[]
736     //-----------------------------------------------------------------------
737     /**
738      * Gets the contents of an <code>InputStream</code> as a character array
739      * using the default character encoding of the platform.
740      * <p>
741      * This method buffers the input internally, so there is no need to use a
742      * <code>BufferedInputStream</code>.
743      *
744      * @param is  the <code>InputStream</code> to read from
745      * @return the requested character array
746      * @throws NullPointerException if the input is null
747      * @throws IOException if an I/O error occurs
748      * @since 1.1
749      * @deprecated 2.5 use {@link #toCharArray(InputStream, Charset)} instead
750      */
751     @Deprecated
752     public static char[] toCharArray(final InputStream is) throws IOException {
753         return toCharArray(is, Charset.defaultCharset());
754     }
755 
756     /**
757      * Gets the contents of an <code>InputStream</code> as a character array
758      * using the specified character encoding.
759      * <p>
760      * This method buffers the input internally, so there is no need to use a
761      * <code>BufferedInputStream</code>.
762      *
763      * @param is  the <code>InputStream</code> to read from
764      * @param encoding  the encoding to use, null means platform default
765      * @return the requested character array
766      * @throws NullPointerException if the input is null
767      * @throws IOException if an I/O error occurs
768      * @since 2.3
769      */
770     public static char[] toCharArray(final InputStream is, final Charset encoding)
771             throws IOException {
772         final CharArrayWriter output = new CharArrayWriter();
773         copy(is, output, encoding);
774         return output.toCharArray();
775     }
776 
777     /**
778      * Gets the contents of an <code>InputStream</code> as a character array
779      * using the specified character encoding.
780      * <p>
781      * Character encoding names can be found at
782      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
783      * <p>
784      * This method buffers the input internally, so there is no need to use a
785      * <code>BufferedInputStream</code>.
786      *
787      * @param is  the <code>InputStream</code> to read from
788      * @param encoding  the encoding to use, null means platform default
789      * @return the requested character array
790      * @throws NullPointerException if the input is null
791      * @throws IOException if an I/O error occurs
792      * @throws UnsupportedCharsetException
793      *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
794      *             supported.
795      * @since 1.1
796      */
797     public static char[] toCharArray(final InputStream is, final String encoding) throws IOException {
798         return toCharArray(is, Charsets.toCharset(encoding));
799     }
800 
801     /**
802      * Gets the contents of a <code>Reader</code> as a character array.
803      * <p>
804      * This method buffers the input internally, so there is no need to use a
805      * <code>BufferedReader</code>.
806      *
807      * @param input  the <code>Reader</code> to read from
808      * @return the requested character array
809      * @throws NullPointerException if the input is null
810      * @throws IOException if an I/O error occurs
811      * @since 1.1
812      */
813     public static char[] toCharArray(final Reader input) throws IOException {
814         final CharArrayWriter sw = new CharArrayWriter();
815         copy(input, sw);
816         return sw.toCharArray();
817     }
818 
819     // read toString
820     //-----------------------------------------------------------------------
821     /**
822      * Gets the contents of an <code>InputStream</code> as a String
823      * using the default character encoding of the platform.
824      * <p>
825      * This method buffers the input internally, so there is no need to use a
826      * <code>BufferedInputStream</code>.
827      *
828      * @param input  the <code>InputStream</code> to read from
829      * @return the requested String
830      * @throws NullPointerException if the input is null
831      * @throws IOException if an I/O error occurs
832      * @deprecated 2.5 use {@link #toString(InputStream, Charset)} instead
833      */
834     @Deprecated
835     public static String toString(final InputStream input) throws IOException {
836         return toString(input, Charset.defaultCharset());
837     }
838 
839     /**
840      * Gets the contents of an <code>InputStream</code> as a String
841      * using the specified character encoding.
842      * <p>
843      * This method buffers the input internally, so there is no need to use a
844      * <code>BufferedInputStream</code>.
845      * </p>
846      * @param input  the <code>InputStream</code> to read from
847      * @param encoding  the encoding to use, null means platform default
848      * @return the requested String
849      * @throws NullPointerException if the input is null
850      * @throws IOException if an I/O error occurs
851      * @since 2.3
852      */
853     public static String toString(final InputStream input, final Charset encoding) throws IOException {
854         final StringBuilderWriter sw = new StringBuilderWriter();
855         copy(input, sw, encoding);
856         return sw.toString();
857     }
858 
859     /**
860      * Gets the contents of an <code>InputStream</code> as a String
861      * using the specified character encoding.
862      * <p>
863      * Character encoding names can be found at
864      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
865      * <p>
866      * This method buffers the input internally, so there is no need to use a
867      * <code>BufferedInputStream</code>.
868      *
869      * @param input  the <code>InputStream</code> to read from
870      * @param encoding  the encoding to use, null means platform default
871      * @return the requested String
872      * @throws NullPointerException if the input is null
873      * @throws IOException if an I/O error occurs
874      * @throws UnsupportedCharsetException
875      *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
876      *             supported.
877      */
878     public static String toString(final InputStream input, final String encoding)
879             throws IOException {
880         return toString(input, Charsets.toCharset(encoding));
881     }
882 
883     /**
884      * Gets the contents of a <code>Reader</code> as a String.
885      * <p>
886      * This method buffers the input internally, so there is no need to use a
887      * <code>BufferedReader</code>.
888      *
889      * @param input  the <code>Reader</code> to read from
890      * @return the requested String
891      * @throws NullPointerException if the input is null
892      * @throws IOException if an I/O error occurs
893      */
894     public static String toString(final Reader input) throws IOException {
895         final StringBuilderWriter sw = new StringBuilderWriter();
896         copy(input, sw);
897         return sw.toString();
898     }
899 
900     /**
901      * Gets the contents at the given URI.
902      *
903      * @param uri
904      *            The URI source.
905      * @return The contents of the URL as a String.
906      * @throws IOException if an I/O exception occurs.
907      * @since 2.1
908      * @deprecated 2.5 use {@link #toString(URI, Charset)} instead
909      */
910     @Deprecated
911     public static String toString(final URI uri) throws IOException {
912         return toString(uri, Charset.defaultCharset());
913     }
914 
915     /**
916      * Gets the contents at the given URI.
917      *
918      * @param uri
919      *            The URI source.
920      * @param encoding
921      *            The encoding name for the URL contents.
922      * @return The contents of the URL as a String.
923      * @throws IOException if an I/O exception occurs.
924      * @since 2.3.
925      */
926     public static String toString(final URI uri, final Charset encoding) throws IOException {
927         return toString(uri.toURL(), Charsets.toCharset(encoding));
928     }
929 
930     /**
931      * Gets the contents at the given URI.
932      *
933      * @param uri
934      *            The URI source.
935      * @param encoding
936      *            The encoding name for the URL contents.
937      * @return The contents of the URL as a String.
938      * @throws IOException if an I/O exception occurs.
939      * @throws UnsupportedCharsetException
940      *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
941      *             supported.
942      * @since 2.1
943      */
944     public static String toString(final URI uri, final String encoding) throws IOException {
945         return toString(uri, Charsets.toCharset(encoding));
946     }
947 
948     /**
949      * Gets the contents at the given URL.
950      *
951      * @param url
952      *            The URL source.
953      * @return The contents of the URL as a String.
954      * @throws IOException if an I/O exception occurs.
955      * @since 2.1
956      * @deprecated 2.5 use {@link #toString(URL, Charset)} instead
957      */
958     @Deprecated
959     public static String toString(final URL url) throws IOException {
960         return toString(url, Charset.defaultCharset());
961     }
962 
963     /**
964      * Gets the contents at the given URL.
965      *
966      * @param url
967      *            The URL source.
968      * @param encoding
969      *            The encoding name for the URL contents.
970      * @return The contents of the URL as a String.
971      * @throws IOException if an I/O exception occurs.
972      * @since 2.3
973      */
974     public static String toString(final URL url, final Charset encoding) throws IOException {
975         final InputStream inputStream = url.openStream();
976         try {
977             return toString(inputStream, encoding);
978         } finally {
979             inputStream.close();
980         }
981     }
982 
983     /**
984      * Gets the contents at the given URL.
985      *
986      * @param url
987      *            The URL source.
988      * @param encoding
989      *            The encoding name for the URL contents.
990      * @return The contents of the URL as a String.
991      * @throws IOException if an I/O exception occurs.
992      * @throws UnsupportedCharsetException
993      *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
994      *             supported.
995      * @since 2.1
996      */
997     public static String toString(final URL url, final String encoding) throws IOException {
998         return toString(url, Charsets.toCharset(encoding));
999     }
1000 
1001     /**
1002      * Gets the contents of a <code>byte[]</code> as a String
1003      * using the default character encoding of the platform.
1004      *
1005      * @param input the byte array to read from
1006      * @return the requested String
1007      * @throws NullPointerException if the input is null
1008      * @throws IOException if an I/O error occurs (never occurs)
1009      * @deprecated 2.5 Use {@link String#String(byte[])} instead
1010      */
1011     @Deprecated
1012     public static String toString(final byte[] input) throws IOException {
1013         // make explicit the use of the default charset
1014         return new String(input, Charset.defaultCharset());
1015     }
1016 
1017     /**
1018      * Gets the contents of a <code>byte[]</code> as a String
1019      * using the specified character encoding.
1020      * <p>
1021      * Character encoding names can be found at
1022      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1023      *
1024      * @param input the byte array to read from
1025      * @param encoding  the encoding to use, null means platform default
1026      * @return the requested String
1027      * @throws NullPointerException if the input is null
1028      * @throws IOException if an I/O error occurs (never occurs)
1029      */
1030     public static String toString(final byte[] input, final String encoding) throws IOException {
1031         return new String(input, Charsets.toCharset(encoding));
1032     }
1033 
1034     // readLines
1035     //-----------------------------------------------------------------------
1036     /**
1037      * Gets the contents of an <code>InputStream</code> as a list of Strings,
1038      * one entry per line, using the default character encoding of the platform.
1039      * <p>
1040      * This method buffers the input internally, so there is no need to use a
1041      * <code>BufferedInputStream</code>.
1042      *
1043      * @param input  the <code>InputStream</code> to read from, not null
1044      * @return the list of Strings, never null
1045      * @throws NullPointerException if the input is null
1046      * @throws IOException if an I/O error occurs
1047      * @since 1.1
1048      * @deprecated 2.5 use {@link #readLines(InputStream, Charset)} instead
1049      */
1050     @Deprecated
1051     public static List<String> readLines(final InputStream input) throws IOException {
1052         return readLines(input, Charset.defaultCharset());
1053     }
1054 
1055     /**
1056      * Gets the contents of an <code>InputStream</code> as a list of Strings,
1057      * one entry per line, using the specified character encoding.
1058      * <p>
1059      * This method buffers the input internally, so there is no need to use a
1060      * <code>BufferedInputStream</code>.
1061      *
1062      * @param input  the <code>InputStream</code> to read from, not null
1063      * @param encoding  the encoding to use, null means platform default
1064      * @return the list of Strings, never null
1065      * @throws NullPointerException if the input is null
1066      * @throws IOException if an I/O error occurs
1067      * @since 2.3
1068      */
1069     public static List<String> readLines(final InputStream input, final Charset encoding) throws IOException {
1070         final InputStreamReader reader = new InputStreamReader(input, Charsets.toCharset(encoding));
1071         return readLines(reader);
1072     }
1073 
1074     /**
1075      * Gets the contents of an <code>InputStream</code> as a list of Strings,
1076      * one entry per line, using the specified character encoding.
1077      * <p>
1078      * Character encoding names can be found at
1079      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1080      * <p>
1081      * This method buffers the input internally, so there is no need to use a
1082      * <code>BufferedInputStream</code>.
1083      *
1084      * @param input  the <code>InputStream</code> to read from, not null
1085      * @param encoding  the encoding to use, null means platform default
1086      * @return the list of Strings, never null
1087      * @throws NullPointerException if the input is null
1088      * @throws IOException if an I/O error occurs
1089      * @throws UnsupportedCharsetException
1090      *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1091      *             supported.
1092      * @since 1.1
1093      */
1094     public static List<String> readLines(final InputStream input, final String encoding) throws IOException {
1095         return readLines(input, Charsets.toCharset(encoding));
1096     }
1097 
1098     /**
1099      * Gets the contents of a <code>Reader</code> as a list of Strings,
1100      * one entry per line.
1101      * <p>
1102      * This method buffers the input internally, so there is no need to use a
1103      * <code>BufferedReader</code>.
1104      *
1105      * @param input  the <code>Reader</code> to read from, not null
1106      * @return the list of Strings, never null
1107      * @throws NullPointerException if the input is null
1108      * @throws IOException if an I/O error occurs
1109      * @since 1.1
1110      */
1111     public static List<String> readLines(final Reader input) throws IOException {
1112         final BufferedReader reader = toBufferedReader(input);
1113         final List<String> list = new ArrayList<String>();
1114         String line = reader.readLine();
1115         while (line != null) {
1116             list.add(line);
1117             line = reader.readLine();
1118         }
1119         return list;
1120     }
1121 
1122     // lineIterator
1123     //-----------------------------------------------------------------------
1124     /**
1125      * Returns an Iterator for the lines in a <code>Reader</code>.
1126      * <p>
1127      * <code>LineIterator</code> holds a reference to the open
1128      * <code>Reader</code> specified here. When you have finished with the
1129      * iterator you should close the reader to free internal resources.
1130      * This can be done by closing the reader directly, or by calling
1131      * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
1132      * <p>
1133      * The recommended usage pattern is:
1134      * <pre>
1135      * try {
1136      *   LineIterator it = IOUtils.lineIterator(reader);
1137      *   while (it.hasNext()) {
1138      *     String line = it.nextLine();
1139      *     /// do something with line
1140      *   }
1141      * } finally {
1142      *   IOUtils.closeQuietly(reader);
1143      * }
1144      * </pre>
1145      *
1146      * @param reader  the <code>Reader</code> to read from, not null
1147      * @return an Iterator of the lines in the reader, never null
1148      * @throws IllegalArgumentException if the reader is null
1149      * @since 1.2
1150      */
1151     public static LineIterator lineIterator(final Reader reader) {
1152         return new LineIterator(reader);
1153     }
1154 
1155     /**
1156      * Returns an Iterator for the lines in an <code>InputStream</code>, using
1157      * the character encoding specified (or default encoding if null).
1158      * <p>
1159      * <code>LineIterator</code> holds a reference to the open
1160      * <code>InputStream</code> specified here. When you have finished with
1161      * the iterator you should close the stream to free internal resources.
1162      * This can be done by closing the stream directly, or by calling
1163      * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
1164      * <p>
1165      * The recommended usage pattern is:
1166      * <pre>
1167      * try {
1168      *   LineIterator it = IOUtils.lineIterator(stream, charset);
1169      *   while (it.hasNext()) {
1170      *     String line = it.nextLine();
1171      *     /// do something with line
1172      *   }
1173      * } finally {
1174      *   IOUtils.closeQuietly(stream);
1175      * }
1176      * </pre>
1177      *
1178      * @param input  the <code>InputStream</code> to read from, not null
1179      * @param encoding  the encoding to use, null means platform default
1180      * @return an Iterator of the lines in the reader, never null
1181      * @throws IllegalArgumentException if the input is null
1182      * @throws IOException if an I/O error occurs, such as if the encoding is invalid
1183      * @since 2.3
1184      */
1185     public static LineIterator lineIterator(final InputStream input, final Charset encoding) throws IOException {
1186         return new LineIterator(new InputStreamReader(input, Charsets.toCharset(encoding)));
1187     }
1188 
1189     /**
1190      * Returns an Iterator for the lines in an <code>InputStream</code>, using
1191      * the character encoding specified (or default encoding if null).
1192      * <p>
1193      * <code>LineIterator</code> holds a reference to the open
1194      * <code>InputStream</code> specified here. When you have finished with
1195      * the iterator you should close the stream to free internal resources.
1196      * This can be done by closing the stream directly, or by calling
1197      * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
1198      * <p>
1199      * The recommended usage pattern is:
1200      * <pre>
1201      * try {
1202      *   LineIterator it = IOUtils.lineIterator(stream, "UTF-8");
1203      *   while (it.hasNext()) {
1204      *     String line = it.nextLine();
1205      *     /// do something with line
1206      *   }
1207      * } finally {
1208      *   IOUtils.closeQuietly(stream);
1209      * }
1210      * </pre>
1211      *
1212      * @param input  the <code>InputStream</code> to read from, not null
1213      * @param encoding  the encoding to use, null means platform default
1214      * @return an Iterator of the lines in the reader, never null
1215      * @throws IllegalArgumentException if the input is null
1216      * @throws IOException if an I/O error occurs, such as if the encoding is invalid
1217      * @throws UnsupportedCharsetException
1218      *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1219      *             supported.
1220      * @since 1.2
1221      */
1222     public static LineIterator lineIterator(final InputStream input, final String encoding) throws IOException {
1223         return lineIterator(input, Charsets.toCharset(encoding));
1224     }
1225 
1226     //-----------------------------------------------------------------------
1227     /**
1228      * Converts the specified CharSequence to an input stream, encoded as bytes
1229      * using the default character encoding of the platform.
1230      *
1231      * @param input the CharSequence to convert
1232      * @return an input stream
1233      * @since 2.0
1234      * @deprecated 2.5 use {@link #toInputStream(CharSequence, Charset)} instead
1235      */
1236     @Deprecated
1237     public static InputStream toInputStream(final CharSequence input) {
1238         return toInputStream(input, Charset.defaultCharset());
1239     }
1240 
1241     /**
1242      * Converts the specified CharSequence to an input stream, encoded as bytes
1243      * using the specified character encoding.
1244      *
1245      * @param input the CharSequence to convert
1246      * @param encoding the encoding to use, null means platform default
1247      * @return an input stream
1248      * @since 2.3
1249      */
1250     public static InputStream toInputStream(final CharSequence input, final Charset encoding) {
1251         return toInputStream(input.toString(), encoding);
1252     }
1253 
1254     /**
1255      * Converts the specified CharSequence to an input stream, encoded as bytes
1256      * using the specified character encoding.
1257      * <p>
1258      * Character encoding names can be found at
1259      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1260      *
1261      * @param input the CharSequence to convert
1262      * @param encoding the encoding to use, null means platform default
1263      * @return an input stream
1264      * @throws IOException if the encoding is invalid
1265      * @throws UnsupportedCharsetException
1266      *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1267      *             supported.
1268      * @since 2.0
1269      */
1270     public static InputStream toInputStream(final CharSequence input, final String encoding) throws IOException {
1271         return toInputStream(input, Charsets.toCharset(encoding));
1272     }
1273 
1274     //-----------------------------------------------------------------------
1275     /**
1276      * Converts the specified string to an input stream, encoded as bytes
1277      * using the default character encoding of the platform.
1278      *
1279      * @param input the string to convert
1280      * @return an input stream
1281      * @since 1.1
1282      * @deprecated 2.5 use {@link #toInputStream(String, Charset)} instead
1283      */
1284     @Deprecated
1285     public static InputStream toInputStream(final String input) {
1286         return toInputStream(input, Charset.defaultCharset());
1287     }
1288 
1289     /**
1290      * Converts the specified string to an input stream, encoded as bytes
1291      * using the specified character encoding.
1292      *
1293      * @param input the string to convert
1294      * @param encoding the encoding to use, null means platform default
1295      * @return an input stream
1296      * @since 2.3
1297      */
1298     public static InputStream toInputStream(final String input, final Charset encoding) {
1299         return new ByteArrayInputStream(input.getBytes(Charsets.toCharset(encoding)));
1300     }
1301 
1302     /**
1303      * Converts the specified string to an input stream, encoded as bytes
1304      * using the specified character encoding.
1305      * <p>
1306      * Character encoding names can be found at
1307      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1308      *
1309      * @param input the string to convert
1310      * @param encoding the encoding to use, null means platform default
1311      * @return an input stream
1312      * @throws IOException if the encoding is invalid
1313      * @throws UnsupportedCharsetException
1314      *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1315      *             supported.
1316      * @since 1.1
1317      */
1318     public static InputStream toInputStream(final String input, final String encoding) throws IOException {
1319         final byte[] bytes = input.getBytes(Charsets.toCharset(encoding));
1320         return new ByteArrayInputStream(bytes);
1321     }
1322 
1323     // write byte[]
1324     //-----------------------------------------------------------------------
1325     /**
1326      * Writes bytes from a <code>byte[]</code> to an <code>OutputStream</code>.
1327      *
1328      * @param data  the byte array to write, do not modify during output,
1329      * null ignored
1330      * @param output  the <code>OutputStream</code> to write to
1331      * @throws NullPointerException if output is null
1332      * @throws IOException if an I/O error occurs
1333      * @since 1.1
1334      */
1335     public static void write(final byte[] data, final OutputStream output)
1336             throws IOException {
1337         if (data != null) {
1338             output.write(data);
1339         }
1340     }
1341 
1342     /**
1343      * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code>
1344      * using the default character encoding of the platform.
1345      * <p>
1346      * This method uses {@link String#String(byte[])}.
1347      *
1348      * @param data  the byte array to write, do not modify during output,
1349      * null ignored
1350      * @param output  the <code>Writer</code> to write to
1351      * @throws NullPointerException if output is null
1352      * @throws IOException if an I/O error occurs
1353      * @since 1.1
1354      * @deprecated 2.5 use {@link #write(byte[], Writer, Charset)} instead
1355      */
1356     @Deprecated
1357     public static void write(final byte[] data, final Writer output) throws IOException {
1358         write(data, output, Charset.defaultCharset());
1359     }
1360 
1361     /**
1362      * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code>
1363      * using the specified character encoding.
1364      * <p>
1365      * This method uses {@link String#String(byte[], String)}.
1366      *
1367      * @param data  the byte array to write, do not modify during output,
1368      * null ignored
1369      * @param output  the <code>Writer</code> to write to
1370      * @param encoding  the encoding to use, null means platform default
1371      * @throws NullPointerException if output is null
1372      * @throws IOException if an I/O error occurs
1373      * @since 2.3
1374      */
1375     public static void write(final byte[] data, final Writer output, final Charset encoding) throws IOException {
1376         if (data != null) {
1377             output.write(new String(data, Charsets.toCharset(encoding)));
1378         }
1379     }
1380 
1381     /**
1382      * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code>
1383      * using the specified character encoding.
1384      * <p>
1385      * Character encoding names can be found at
1386      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1387      * <p>
1388      * This method uses {@link String#String(byte[], String)}.
1389      *
1390      * @param data  the byte array to write, do not modify during output,
1391      * null ignored
1392      * @param output  the <code>Writer</code> to write to
1393      * @param encoding  the encoding to use, null means platform default
1394      * @throws NullPointerException if output is null
1395      * @throws IOException if an I/O error occurs
1396      * @throws UnsupportedCharsetException
1397      *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1398      *             supported.
1399      * @since 1.1
1400      */
1401     public static void write(final byte[] data, final Writer output, final String encoding) throws IOException {
1402         write(data, output, Charsets.toCharset(encoding));
1403     }
1404 
1405     // write char[]
1406     //-----------------------------------------------------------------------
1407     /**
1408      * Writes chars from a <code>char[]</code> to a <code>Writer</code>
1409      * using the default character encoding of the platform.
1410      *
1411      * @param data  the char array to write, do not modify during output,
1412      * null ignored
1413      * @param output  the <code>Writer</code> to write to
1414      * @throws NullPointerException if output is null
1415      * @throws IOException if an I/O error occurs
1416      * @since 1.1
1417      */
1418     public static void write(final char[] data, final Writer output) throws IOException {
1419         if (data != null) {
1420             output.write(data);
1421         }
1422     }
1423 
1424     /**
1425      * Writes chars from a <code>char[]</code> to bytes on an
1426      * <code>OutputStream</code>.
1427      * <p>
1428      * This method uses {@link String#String(char[])} and
1429      * {@link String#getBytes()}.
1430      *
1431      * @param data  the char array to write, do not modify during output,
1432      * null ignored
1433      * @param output  the <code>OutputStream</code> to write to
1434      * @throws NullPointerException if output is null
1435      * @throws IOException if an I/O error occurs
1436      * @since 1.1
1437      * @deprecated 2.5 use {@link #write(char[], OutputStream, Charset)} instead
1438      */
1439     @Deprecated
1440     public static void write(final char[] data, final OutputStream output)
1441             throws IOException {
1442         write(data, output, Charset.defaultCharset());
1443     }
1444 
1445     /**
1446      * Writes chars from a <code>char[]</code> to bytes on an
1447      * <code>OutputStream</code> using the specified character encoding.
1448      * <p>
1449      * This method uses {@link String#String(char[])} and
1450      * {@link String#getBytes(String)}.
1451      *
1452      * @param data  the char array to write, do not modify during output,
1453      * null ignored
1454      * @param output  the <code>OutputStream</code> to write to
1455      * @param encoding  the encoding to use, null means platform default
1456      * @throws NullPointerException if output is null
1457      * @throws IOException if an I/O error occurs
1458      * @since 2.3
1459      */
1460     public static void write(final char[] data, final OutputStream output, final Charset encoding) throws IOException {
1461         if (data != null) {
1462             output.write(new String(data).getBytes(Charsets.toCharset(encoding)));
1463         }
1464     }
1465 
1466     /**
1467      * Writes chars from a <code>char[]</code> to bytes on an
1468      * <code>OutputStream</code> using the specified character encoding.
1469      * <p>
1470      * Character encoding names can be found at
1471      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1472      * <p>
1473      * This method uses {@link String#String(char[])} and
1474      * {@link String#getBytes(String)}.
1475      *
1476      * @param data  the char array to write, do not modify during output,
1477      * null ignored
1478      * @param output  the <code>OutputStream</code> to write to
1479      * @param encoding  the encoding to use, null means platform default
1480      * @throws NullPointerException if output is null
1481      * @throws IOException if an I/O error occurs
1482      * @throws UnsupportedCharsetException
1483      *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1484      *             supported.
1485      * @since 1.1
1486      */
1487     public static void write(final char[] data, final OutputStream output, final String encoding)
1488             throws IOException {
1489         write(data, output, Charsets.toCharset(encoding));
1490     }
1491 
1492     // write CharSequence
1493     //-----------------------------------------------------------------------
1494     /**
1495      * Writes chars from a <code>CharSequence</code> to a <code>Writer</code>.
1496      *
1497      * @param data  the <code>CharSequence</code> to write, null ignored
1498      * @param output  the <code>Writer</code> to write to
1499      * @throws NullPointerException if output is null
1500      * @throws IOException if an I/O error occurs
1501      * @since 2.0
1502      */
1503     public static void write(final CharSequence data, final Writer output) throws IOException {
1504         if (data != null) {
1505             write(data.toString(), output);
1506         }
1507     }
1508 
1509     /**
1510      * Writes chars from a <code>CharSequence</code> to bytes on an
1511      * <code>OutputStream</code> using the default character encoding of the
1512      * platform.
1513      * <p>
1514      * This method uses {@link String#getBytes()}.
1515      *
1516      * @param data  the <code>CharSequence</code> to write, null ignored
1517      * @param output  the <code>OutputStream</code> to write to
1518      * @throws NullPointerException if output is null
1519      * @throws IOException if an I/O error occurs
1520      * @since 2.0
1521      * @deprecated 2.5 use {@link #write(CharSequence, OutputStream, Charset)} instead
1522      */
1523     @Deprecated
1524     public static void write(final CharSequence data, final OutputStream output)
1525             throws IOException {
1526         write(data, output, Charset.defaultCharset());
1527     }
1528 
1529     /**
1530      * Writes chars from a <code>CharSequence</code> to bytes on an
1531      * <code>OutputStream</code> using the specified character encoding.
1532      * <p>
1533      * This method uses {@link String#getBytes(String)}.
1534      *
1535      * @param data  the <code>CharSequence</code> to write, null ignored
1536      * @param output  the <code>OutputStream</code> to write to
1537      * @param encoding  the encoding to use, null means platform default
1538      * @throws NullPointerException if output is null
1539      * @throws IOException if an I/O error occurs
1540      * @since 2.3
1541      */
1542     public static void write(final CharSequence data, final OutputStream output, final Charset encoding) throws IOException {
1543         if (data != null) {
1544             write(data.toString(), output, encoding);
1545         }
1546     }
1547 
1548     /**
1549      * Writes chars from a <code>CharSequence</code> to bytes on an
1550      * <code>OutputStream</code> using the specified character encoding.
1551      * <p>
1552      * Character encoding names can be found at
1553      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1554      * <p>
1555      * This method uses {@link String#getBytes(String)}.
1556      *
1557      * @param data  the <code>CharSequence</code> to write, null ignored
1558      * @param output  the <code>OutputStream</code> to write to
1559      * @param encoding  the encoding to use, null means platform default
1560      * @throws NullPointerException if output is null
1561      * @throws IOException if an I/O error occurs
1562      * @throws UnsupportedCharsetException
1563      *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1564      *             supported.
1565      * @since 2.0
1566      */
1567     public static void write(final CharSequence data, final OutputStream output, final String encoding) throws IOException {
1568         write(data, output, Charsets.toCharset(encoding));
1569     }
1570 
1571     // write String
1572     //-----------------------------------------------------------------------
1573     /**
1574      * Writes chars from a <code>String</code> to a <code>Writer</code>.
1575      *
1576      * @param data  the <code>String</code> to write, null ignored
1577      * @param output  the <code>Writer</code> to write to
1578      * @throws NullPointerException if output is null
1579      * @throws IOException if an I/O error occurs
1580      * @since 1.1
1581      */
1582     public static void write(final String data, final Writer output) throws IOException {
1583         if (data != null) {
1584             output.write(data);
1585         }
1586     }
1587 
1588     /**
1589      * Writes chars from a <code>String</code> to bytes on an
1590      * <code>OutputStream</code> using the default character encoding of the
1591      * platform.
1592      * <p>
1593      * This method uses {@link String#getBytes()}.
1594      *
1595      * @param data  the <code>String</code> to write, null ignored
1596      * @param output  the <code>OutputStream</code> to write to
1597      * @throws NullPointerException if output is null
1598      * @throws IOException if an I/O error occurs
1599      * @since 1.1
1600      * @deprecated 2.5 use {@link #write(String, OutputStream, Charset)} instead
1601      */
1602     @Deprecated
1603     public static void write(final String data, final OutputStream output)
1604             throws IOException {
1605         write(data, output, Charset.defaultCharset());
1606     }
1607 
1608     /**
1609      * Writes chars from a <code>String</code> to bytes on an
1610      * <code>OutputStream</code> using the specified character encoding.
1611      * <p>
1612      * This method uses {@link String#getBytes(String)}.
1613      *
1614      * @param data  the <code>String</code> to write, null ignored
1615      * @param output  the <code>OutputStream</code> to write to
1616      * @param encoding  the encoding to use, null means platform default
1617      * @throws NullPointerException if output is null
1618      * @throws IOException if an I/O error occurs
1619      * @since 2.3
1620      */
1621     public static void write(final String data, final OutputStream output, final Charset encoding) throws IOException {
1622         if (data != null) {
1623             output.write(data.getBytes(Charsets.toCharset(encoding)));
1624         }
1625     }
1626 
1627     /**
1628      * Writes chars from a <code>String</code> to bytes on an
1629      * <code>OutputStream</code> using the specified character encoding.
1630      * <p>
1631      * Character encoding names can be found at
1632      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1633      * <p>
1634      * This method uses {@link String#getBytes(String)}.
1635      *
1636      * @param data  the <code>String</code> to write, null ignored
1637      * @param output  the <code>OutputStream</code> to write to
1638      * @param encoding  the encoding to use, null means platform default
1639      * @throws NullPointerException if output is null
1640      * @throws IOException if an I/O error occurs
1641      * @throws UnsupportedCharsetException
1642      *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1643      *             supported.
1644      * @since 1.1
1645      */
1646     public static void write(final String data, final OutputStream output, final String encoding)
1647             throws IOException {
1648         write(data, output, Charsets.toCharset(encoding));
1649     }
1650 
1651     // write StringBuffer
1652     //-----------------------------------------------------------------------
1653     /**
1654      * Writes chars from a <code>StringBuffer</code> to a <code>Writer</code>.
1655      *
1656      * @param data  the <code>StringBuffer</code> to write, null ignored
1657      * @param output  the <code>Writer</code> to write to
1658      * @throws NullPointerException if output is null
1659      * @throws IOException if an I/O error occurs
1660      * @since 1.1
1661      * @deprecated replaced by write(CharSequence, Writer)
1662      */
1663     @Deprecated
1664     public static void write(final StringBuffer data, final Writer output)
1665             throws IOException {
1666         if (data != null) {
1667             output.write(data.toString());
1668         }
1669     }
1670 
1671     /**
1672      * Writes chars from a <code>StringBuffer</code> to bytes on an
1673      * <code>OutputStream</code> using the default character encoding of the
1674      * platform.
1675      * <p>
1676      * This method uses {@link String#getBytes()}.
1677      *
1678      * @param data  the <code>StringBuffer</code> to write, null ignored
1679      * @param output  the <code>OutputStream</code> to write to
1680      * @throws NullPointerException if output is null
1681      * @throws IOException if an I/O error occurs
1682      * @since 1.1
1683      * @deprecated replaced by write(CharSequence, OutputStream)
1684      */
1685     @Deprecated
1686     public static void write(final StringBuffer data, final OutputStream output)
1687             throws IOException {
1688         write(data, output, (String) null);
1689     }
1690 
1691     /**
1692      * Writes chars from a <code>StringBuffer</code> to bytes on an
1693      * <code>OutputStream</code> using the specified character encoding.
1694      * <p>
1695      * Character encoding names can be found at
1696      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1697      * <p>
1698      * This method uses {@link String#getBytes(String)}.
1699      *
1700      * @param data  the <code>StringBuffer</code> to write, null ignored
1701      * @param output  the <code>OutputStream</code> to write to
1702      * @param encoding  the encoding to use, null means platform default
1703      * @throws NullPointerException if output is null
1704      * @throws IOException if an I/O error occurs
1705      * @throws UnsupportedCharsetException
1706      *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1707      *             supported.
1708      * @since 1.1
1709      * @deprecated replaced by write(CharSequence, OutputStream, String)
1710      */
1711     @Deprecated
1712     public static void write(final StringBuffer data, final OutputStream output, final String encoding) throws IOException {
1713         if (data != null) {
1714             output.write(data.toString().getBytes(Charsets.toCharset(encoding)));
1715         }
1716     }
1717 
1718     // writeLines
1719     //-----------------------------------------------------------------------
1720     /**
1721      * Writes the <code>toString()</code> value of each item in a collection to
1722      * an <code>OutputStream</code> line by line, using the default character
1723      * encoding of the platform and the specified line ending.
1724      *
1725      * @param lines  the lines to write, null entries produce blank lines
1726      * @param lineEnding  the line separator to use, null is system default
1727      * @param output  the <code>OutputStream</code> to write to, not null, not closed
1728      * @throws NullPointerException if the output is null
1729      * @throws IOException if an I/O error occurs
1730      * @since 1.1
1731      * @deprecated 2.5 use {@link #writeLines(Collection, String, OutputStream, Charset)} instead
1732      */
1733     @Deprecated
1734     public static void writeLines(final Collection<?> lines, final String lineEnding,
1735             final OutputStream output) throws IOException {
1736         writeLines(lines, lineEnding, output, Charset.defaultCharset());
1737     }
1738 
1739     /**
1740      * Writes the <code>toString()</code> value of each item in a collection to
1741      * an <code>OutputStream</code> line by line, using the specified character
1742      * encoding and the specified line ending.
1743      *
1744      * @param lines  the lines to write, null entries produce blank lines
1745      * @param lineEnding  the line separator to use, null is system default
1746      * @param output  the <code>OutputStream</code> to write to, not null, not closed
1747      * @param encoding  the encoding to use, null means platform default
1748      * @throws NullPointerException if the output is null
1749      * @throws IOException if an I/O error occurs
1750      * @since 2.3
1751      */
1752     public static void writeLines(final Collection<?> lines, String lineEnding, final OutputStream output, final Charset encoding)
1753             throws IOException {
1754         if (lines == null) {
1755             return;
1756         }
1757         if (lineEnding == null) {
1758             lineEnding = LINE_SEPARATOR;
1759         }
1760         final Charset cs = Charsets.toCharset(encoding);
1761         for (final Object line : lines) {
1762             if (line != null) {
1763                 output.write(line.toString().getBytes(cs));
1764             }
1765             output.write(lineEnding.getBytes(cs));
1766         }
1767     }
1768 
1769     /**
1770      * Writes the <code>toString()</code> value of each item in a collection to
1771      * an <code>OutputStream</code> line by line, using the specified character
1772      * encoding and the specified line ending.
1773      * <p>
1774      * Character encoding names can be found at
1775      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1776      *
1777      * @param lines  the lines to write, null entries produce blank lines
1778      * @param lineEnding  the line separator to use, null is system default
1779      * @param output  the <code>OutputStream</code> to write to, not null, not closed
1780      * @param encoding  the encoding to use, null means platform default
1781      * @throws NullPointerException if the output is null
1782      * @throws IOException if an I/O error occurs
1783      * @throws UnsupportedCharsetException
1784      *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1785      *             supported.
1786      * @since 1.1
1787      */
1788     public static void writeLines(final Collection<?> lines, final String lineEnding,
1789             final OutputStream output, final String encoding) throws IOException {
1790         writeLines(lines, lineEnding, output, Charsets.toCharset(encoding));
1791     }
1792 
1793     /**
1794      * Writes the <code>toString()</code> value of each item in a collection to
1795      * a <code>Writer</code> line by line, using the specified line ending.
1796      *
1797      * @param lines  the lines to write, null entries produce blank lines
1798      * @param lineEnding  the line separator to use, null is system default
1799      * @param writer  the <code>Writer</code> to write to, not null, not closed
1800      * @throws NullPointerException if the input is null
1801      * @throws IOException if an I/O error occurs
1802      * @since 1.1
1803      */
1804     public static void writeLines(final Collection<?> lines, String lineEnding,
1805             final Writer writer) throws IOException {
1806         if (lines == null) {
1807             return;
1808         }
1809         if (lineEnding == null) {
1810             lineEnding = LINE_SEPARATOR;
1811         }
1812         for (final Object line : lines) {
1813             if (line != null) {
1814                 writer.write(line.toString());
1815             }
1816             writer.write(lineEnding);
1817         }
1818     }
1819 
1820     // copy from InputStream
1821     //-----------------------------------------------------------------------
1822     /**
1823      * Copies bytes from an <code>InputStream</code> to an
1824      * <code>OutputStream</code>.
1825      * <p>
1826      * This method buffers the input internally, so there is no need to use a
1827      * <code>BufferedInputStream</code>.
1828      * <p>
1829      * Large streams (over 2GB) will return a bytes copied value of
1830      * <code>-1</code> after the copy has completed since the correct
1831      * number of bytes cannot be returned as an int. For large streams
1832      * use the <code>copyLarge(InputStream, OutputStream)</code> method.
1833      *
1834      * @param input  the <code>InputStream</code> to read from
1835      * @param output  the <code>OutputStream</code> to write to
1836      * @return the number of bytes copied, or -1 if &gt; Integer.MAX_VALUE
1837      * @throws NullPointerException if the input or output is null
1838      * @throws IOException if an I/O error occurs
1839      * @since 1.1
1840      */
1841     public static int copy(final InputStream input, final OutputStream output) throws IOException {
1842         final long count = copyLarge(input, output);
1843         if (count > Integer.MAX_VALUE) {
1844             return -1;
1845         }
1846         return (int) count;
1847     }
1848 
1849     /**
1850      * Copies bytes from an <code>InputStream</code> to an <code>OutputStream</code> using an internal buffer of the
1851      * given size.
1852      * <p>
1853      * This method buffers the input internally, so there is no need to use a <code>BufferedInputStream</code>.
1854      * <p>
1855      *
1856      * @param input
1857      *            the <code>InputStream</code> to read from
1858      * @param output
1859      *            the <code>OutputStream</code> to write to
1860      * @param bufferSize
1861      *            the bufferSize used to copy from the input to the output
1862      * @return the number of bytes copied
1863      * @throws NullPointerException
1864      *             if the input or output is null
1865      * @throws IOException
1866      *             if an I/O error occurs
1867      * @since 2.5
1868      */
1869     public static long copy(final InputStream input, final OutputStream output, final int bufferSize) throws IOException {
1870         return copyLarge(input, output, new byte[bufferSize]);
1871     }
1872 
1873     /**
1874      * Copies bytes from a large (over 2GB) <code>InputStream</code> to an
1875      * <code>OutputStream</code>.
1876      * <p>
1877      * This method buffers the input internally, so there is no need to use a
1878      * <code>BufferedInputStream</code>.
1879      * <p>
1880      * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
1881      *
1882      * @param input  the <code>InputStream</code> to read from
1883      * @param output  the <code>OutputStream</code> to write to
1884      * @return the number of bytes copied
1885      * @throws NullPointerException if the input or output is null
1886      * @throws IOException if an I/O error occurs
1887      * @since 1.3
1888      */
1889     public static long copyLarge(final InputStream input, final OutputStream output)
1890             throws IOException {
1891         return copy(input, output, DEFAULT_BUFFER_SIZE);
1892     }
1893 
1894     /**
1895      * Copies bytes from a large (over 2GB) <code>InputStream</code> to an
1896      * <code>OutputStream</code>.
1897      * <p>
1898      * This method uses the provided buffer, so there is no need to use a
1899      * <code>BufferedInputStream</code>.
1900      * <p>
1901      *
1902      * @param input  the <code>InputStream</code> to read from
1903      * @param output  the <code>OutputStream</code> to write to
1904      * @param buffer the buffer to use for the copy
1905      * @return the number of bytes copied
1906      * @throws NullPointerException if the input or output is null
1907      * @throws IOException if an I/O error occurs
1908      * @since 2.2
1909      */
1910     public static long copyLarge(final InputStream input, final OutputStream output, final byte[] buffer)
1911             throws IOException {
1912         long count = 0;
1913         int n = 0;
1914         while (EOF != (n = input.read(buffer))) {
1915             output.write(buffer, 0, n);
1916             count += n;
1917         }
1918         return count;
1919     }
1920 
1921     /**
1922      * Copies some or all bytes from a large (over 2GB) <code>InputStream</code> to an
1923      * <code>OutputStream</code>, optionally skipping input bytes.
1924      * <p>
1925      * This method buffers the input internally, so there is no need to use a
1926      * <code>BufferedInputStream</code>.
1927      * </p>
1928      * <p>
1929      * Note that the implementation uses {@link #skip(InputStream, long)}.
1930      * This means that the method may be considerably less efficient than using the actual skip implementation,
1931      * this is done to guarantee that the correct number of characters are skipped.
1932      * </p>
1933      * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
1934      *
1935      * @param input  the <code>InputStream</code> to read from
1936      * @param output  the <code>OutputStream</code> to write to
1937      * @param inputOffset : number of bytes to skip from input before copying
1938      *         -ve values are ignored
1939      * @param length : number of bytes to copy. -ve means all
1940      * @return the number of bytes copied
1941      * @throws NullPointerException if the input or output is null
1942      * @throws IOException if an I/O error occurs
1943      * @since 2.2
1944      */
1945     public static long copyLarge(final InputStream input, final OutputStream output, final long inputOffset, final long length)
1946             throws IOException {
1947         return copyLarge(input, output, inputOffset, length, new byte[DEFAULT_BUFFER_SIZE]);
1948     }
1949 
1950     /**
1951      * Copies some or all bytes from a large (over 2GB) <code>InputStream</code> to an
1952      * <code>OutputStream</code>, optionally skipping input bytes.
1953      * <p>
1954      * This method uses the provided buffer, so there is no need to use a
1955      * <code>BufferedInputStream</code>.
1956      * </p>
1957      * <p>
1958      * Note that the implementation uses {@link #skip(InputStream, long)}.
1959      * This means that the method may be considerably less efficient than using the actual skip implementation,
1960      * this is done to guarantee that the correct number of characters are skipped.
1961      * </p>
1962      *
1963      * @param input  the <code>InputStream</code> to read from
1964      * @param output  the <code>OutputStream</code> to write to
1965      * @param inputOffset : number of bytes to skip from input before copying
1966      *         -ve values are ignored
1967      * @param length : number of bytes to copy. -ve means all
1968      * @param buffer the buffer to use for the copy
1969      *
1970      * @return the number of bytes copied
1971      * @throws NullPointerException if the input or output is null
1972      * @throws IOException if an I/O error occurs
1973      * @since 2.2
1974      */
1975     public static long copyLarge(final InputStream input, final OutputStream output,
1976             final long inputOffset, final long length, final byte[] buffer)  throws IOException {
1977         if (inputOffset > 0) {
1978             skipFully(input, inputOffset);
1979         }
1980         if (length == 0) {
1981             return 0;
1982         }
1983         final int bufferLength = buffer.length;
1984         int bytesToRead = bufferLength;
1985         if (length > 0 && length < bufferLength) {
1986             bytesToRead = (int) length;
1987         }
1988         int read;
1989         long totalRead = 0;
1990         while (bytesToRead > 0 && EOF != (read = input.read(buffer, 0, bytesToRead))) {
1991             output.write(buffer, 0, read);
1992             totalRead += read;
1993             if (length > 0) { // only adjust length if not reading to the end
1994                 // Note the cast must work because buffer.length is an integer
1995                 bytesToRead = (int) Math.min(length - totalRead, bufferLength);
1996             }
1997         }
1998         return totalRead;
1999     }
2000 
2001     /**
2002      * Copies bytes from an <code>InputStream</code> to chars on a
2003      * <code>Writer</code> using the default character encoding of the platform.
2004      * <p>
2005      * This method buffers the input internally, so there is no need to use a
2006      * <code>BufferedInputStream</code>.
2007      * <p>
2008      * This method uses {@link InputStreamReader}.
2009      *
2010      * @param input  the <code>InputStream</code> to read from
2011      * @param output  the <code>Writer</code> to write to
2012      * @throws NullPointerException if the input or output is null
2013      * @throws IOException if an I/O error occurs
2014      * @since 1.1
2015      * @deprecated 2.5 use {@link #copy(InputStream, Writer, Charset)} instead
2016      */
2017     @Deprecated
2018     public static void copy(final InputStream input, final Writer output)
2019             throws IOException {
2020         copy(input, output, Charset.defaultCharset());
2021     }
2022 
2023     /**
2024      * Copies bytes from an <code>InputStream</code> to chars on a
2025      * <code>Writer</code> using the specified character encoding.
2026      * <p>
2027      * This method buffers the input internally, so there is no need to use a
2028      * <code>BufferedInputStream</code>.
2029      * <p>
2030      * This method uses {@link InputStreamReader}.
2031      *
2032      * @param input  the <code>InputStream</code> to read from
2033      * @param output  the <code>Writer</code> to write to
2034      * @param inputEncoding  the encoding to use for the input stream, null means platform default
2035      * @throws NullPointerException if the input or output is null
2036      * @throws IOException if an I/O error occurs
2037      * @since 2.3
2038      */
2039     public static void copy(final InputStream input, final Writer output, final Charset inputEncoding) throws IOException {
2040         final InputStreamReader in = new InputStreamReader(input, Charsets.toCharset(inputEncoding));
2041         copy(in, output);
2042     }
2043 
2044     /**
2045      * Copies bytes from an <code>InputStream</code> to chars on a
2046      * <code>Writer</code> using the specified character encoding.
2047      * <p>
2048      * This method buffers the input internally, so there is no need to use a
2049      * <code>BufferedInputStream</code>.
2050      * <p>
2051      * Character encoding names can be found at
2052      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
2053      * <p>
2054      * This method uses {@link InputStreamReader}.
2055      *
2056      * @param input  the <code>InputStream</code> to read from
2057      * @param output  the <code>Writer</code> to write to
2058      * @param inputEncoding  the encoding to use for the InputStream, null means platform default
2059      * @throws NullPointerException if the input or output is null
2060      * @throws IOException if an I/O error occurs
2061      * @throws UnsupportedCharsetException
2062      *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
2063      *             supported.
2064      * @since 1.1
2065      */
2066     public static void copy(final InputStream input, final Writer output, final String inputEncoding) throws IOException {
2067         copy(input, output, Charsets.toCharset(inputEncoding));
2068     }
2069 
2070     // copy from Reader
2071     //-----------------------------------------------------------------------
2072     /**
2073      * Copies chars from a <code>Reader</code> to a <code>Writer</code>.
2074      * <p>
2075      * This method buffers the input internally, so there is no need to use a
2076      * <code>BufferedReader</code>.
2077      * <p>
2078      * Large streams (over 2GB) will return a chars copied value of
2079      * <code>-1</code> after the copy has completed since the correct
2080      * number of chars cannot be returned as an int. For large streams
2081      * use the <code>copyLarge(Reader, Writer)</code> method.
2082      *
2083      * @param input  the <code>Reader</code> to read from
2084      * @param output  the <code>Writer</code> to write to
2085      * @return the number of characters copied, or -1 if &gt; Integer.MAX_VALUE
2086      * @throws NullPointerException if the input or output is null
2087      * @throws IOException if an I/O error occurs
2088      * @since 1.1
2089      */
2090     public static int copy(final Reader input, final Writer output) throws IOException {
2091         final long count = copyLarge(input, output);
2092         if (count > Integer.MAX_VALUE) {
2093             return -1;
2094         }
2095         return (int) count;
2096     }
2097 
2098     /**
2099      * Copies chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>.
2100      * <p>
2101      * This method buffers the input internally, so there is no need to use a
2102      * <code>BufferedReader</code>.
2103      * <p>
2104      * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
2105      *
2106      * @param input  the <code>Reader</code> to read from
2107      * @param output  the <code>Writer</code> to write to
2108      * @return the number of characters copied
2109      * @throws NullPointerException if the input or output is null
2110      * @throws IOException if an I/O error occurs
2111      * @since 1.3
2112      */
2113     public static long copyLarge(final Reader input, final Writer output) throws IOException {
2114         return copyLarge(input, output, new char[DEFAULT_BUFFER_SIZE]);
2115     }
2116 
2117     /**
2118      * Copies chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>.
2119      * <p>
2120      * This method uses the provided buffer, so there is no need to use a
2121      * <code>BufferedReader</code>.
2122      * <p>
2123      *
2124      * @param input  the <code>Reader</code> to read from
2125      * @param output  the <code>Writer</code> to write to
2126      * @param buffer the buffer to be used for the copy
2127      * @return the number of characters copied
2128      * @throws NullPointerException if the input or output is null
2129      * @throws IOException if an I/O error occurs
2130      * @since 2.2
2131      */
2132     public static long copyLarge(final Reader input, final Writer output, final char [] buffer) throws IOException {
2133         long count = 0;
2134         int n = 0;
2135         while (EOF != (n = input.read(buffer))) {
2136             output.write(buffer, 0, n);
2137             count += n;
2138         }
2139         return count;
2140     }
2141 
2142     /**
2143      * Copies some or all chars from a large (over 2GB) <code>InputStream</code> to an
2144      * <code>OutputStream</code>, optionally skipping input chars.
2145      * <p>
2146      * This method buffers the input internally, so there is no need to use a
2147      * <code>BufferedReader</code>.
2148      * <p>
2149      * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
2150      *
2151      * @param input  the <code>Reader</code> to read from
2152      * @param output  the <code>Writer</code> to write to
2153      * @param inputOffset : number of chars to skip from input before copying
2154      *         -ve values are ignored
2155      * @param length : number of chars to copy. -ve means all
2156      * @return the number of chars copied
2157      * @throws NullPointerException if the input or output is null
2158      * @throws IOException if an I/O error occurs
2159      * @since 2.2
2160      */
2161     public static long copyLarge(final Reader input, final Writer output, final long inputOffset, final long length)
2162             throws IOException {
2163         return  copyLarge(input, output, inputOffset, length, new char[DEFAULT_BUFFER_SIZE]);
2164     }
2165 
2166     /**
2167      * Copies some or all chars from a large (over 2GB) <code>InputStream</code> to an
2168      * <code>OutputStream</code>, optionally skipping input chars.
2169      * <p>
2170      * This method uses the provided buffer, so there is no need to use a
2171      * <code>BufferedReader</code>.
2172      * <p>
2173      *
2174      * @param input  the <code>Reader</code> to read from
2175      * @param output  the <code>Writer</code> to write to
2176      * @param inputOffset : number of chars to skip from input before copying
2177      *         -ve values are ignored
2178      * @param length : number of chars to copy. -ve means all
2179      * @param buffer the buffer to be used for the copy
2180      * @return the number of chars copied
2181      * @throws NullPointerException if the input or output is null
2182      * @throws IOException if an I/O error occurs
2183      * @since 2.2
2184      */
2185     public static long copyLarge(final Reader input, final Writer output, final long inputOffset, final long length, final char [] buffer)
2186             throws IOException {
2187         if (inputOffset > 0) {
2188             skipFully(input, inputOffset);
2189         }
2190         if (length == 0) {
2191             return 0;
2192         }
2193         int bytesToRead = buffer.length;
2194         if (length > 0 && length < buffer.length) {
2195             bytesToRead = (int) length;
2196         }
2197         int read;
2198         long totalRead = 0;
2199         while (bytesToRead > 0 && EOF != (read = input.read(buffer, 0, bytesToRead))) {
2200             output.write(buffer, 0, read);
2201             totalRead += read;
2202             if (length > 0) { // only adjust length if not reading to the end
2203                 // Note the cast must work because buffer.length is an integer
2204                 bytesToRead = (int) Math.min(length - totalRead, buffer.length);
2205             }
2206         }
2207         return totalRead;
2208     }
2209 
2210     /**
2211      * Copies chars from a <code>Reader</code> to bytes on an
2212      * <code>OutputStream</code> using the default character encoding of the
2213      * platform, and calling flush.
2214      * <p>
2215      * This method buffers the input internally, so there is no need to use a
2216      * <code>BufferedReader</code>.
2217      * <p>
2218      * Due to the implementation of OutputStreamWriter, this method performs a
2219      * flush.
2220      * <p>
2221      * This method uses {@link OutputStreamWriter}.
2222      *
2223      * @param input  the <code>Reader</code> to read from
2224      * @param output  the <code>OutputStream</code> to write to
2225      * @throws NullPointerException if the input or output is null
2226      * @throws IOException if an I/O error occurs
2227      * @since 1.1
2228      * @deprecated 2.5 use {@link #copy(Reader, OutputStream, Charset)} instead
2229      */
2230     @Deprecated
2231     public static void copy(final Reader input, final OutputStream output)
2232             throws IOException {
2233         copy(input, output, Charset.defaultCharset());
2234     }
2235 
2236     /**
2237      * Copies chars from a <code>Reader</code> to bytes on an
2238      * <code>OutputStream</code> using the specified character encoding, and
2239      * calling flush.
2240      * <p>
2241      * This method buffers the input internally, so there is no need to use a
2242      * <code>BufferedReader</code>.
2243      * </p>
2244      * <p>
2245      * Due to the implementation of OutputStreamWriter, this method performs a
2246      * flush.
2247      * </p>
2248      * <p>
2249      * This method uses {@link OutputStreamWriter}.
2250      * </p>
2251      *
2252      * @param input  the <code>Reader</code> to read from
2253      * @param output  the <code>OutputStream</code> to write to
2254      * @param outputEncoding  the encoding to use for the OutputStream, null means platform default
2255      * @throws NullPointerException if the input or output is null
2256      * @throws IOException if an I/O error occurs
2257      * @since 2.3
2258      */
2259     public static void copy(final Reader input, final OutputStream output, final Charset outputEncoding) throws IOException {
2260         final OutputStreamWriter out = new OutputStreamWriter(output, Charsets.toCharset(outputEncoding));
2261         copy(input, out);
2262         // XXX Unless anyone is planning on rewriting OutputStreamWriter,
2263         // we have to flush here.
2264         out.flush();
2265     }
2266 
2267     /**
2268      * Copies chars from a <code>Reader</code> to bytes on an
2269      * <code>OutputStream</code> using the specified character encoding, and
2270      * calling flush.
2271      * <p>
2272      * This method buffers the input internally, so there is no need to use a
2273      * <code>BufferedReader</code>.
2274      * <p>
2275      * Character encoding names can be found at
2276      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
2277      * <p>
2278      * Due to the implementation of OutputStreamWriter, this method performs a
2279      * flush.
2280      * <p>
2281      * This method uses {@link OutputStreamWriter}.
2282      *
2283      * @param input  the <code>Reader</code> to read from
2284      * @param output  the <code>OutputStream</code> to write to
2285      * @param outputEncoding  the encoding to use for the OutputStream, null means platform default
2286      * @throws NullPointerException if the input or output is null
2287      * @throws IOException if an I/O error occurs
2288      * @throws UnsupportedCharsetException
2289      *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
2290      *             supported.
2291      * @since 1.1
2292      */
2293     public static void copy(final Reader input, final OutputStream output, final String outputEncoding) throws IOException {
2294         copy(input, output, Charsets.toCharset(outputEncoding));
2295     }
2296 
2297     // content equals
2298     //-----------------------------------------------------------------------
2299     /**
2300      * Compares the contents of two Streams to determine if they are equal or
2301      * not.
2302      * <p>
2303      * This method buffers the input internally using
2304      * <code>BufferedInputStream</code> if they are not already buffered.
2305      *
2306      * @param input1  the first stream
2307      * @param input2  the second stream
2308      * @return true if the content of the streams are equal or they both don't
2309      * exist, false otherwise
2310      * @throws NullPointerException if either input is null
2311      * @throws IOException if an I/O error occurs
2312      */
2313     public static boolean contentEquals(InputStream input1, InputStream input2)
2314             throws IOException {
2315         if (input1 == input2) {
2316             return true;
2317         }
2318         if (!(input1 instanceof BufferedInputStream)) {
2319             input1 = new BufferedInputStream(input1);
2320         }
2321         if (!(input2 instanceof BufferedInputStream)) {
2322             input2 = new BufferedInputStream(input2);
2323         }
2324 
2325         int ch = input1.read();
2326         while (EOF != ch) {
2327             final int ch2 = input2.read();
2328             if (ch != ch2) {
2329                 return false;
2330             }
2331             ch = input1.read();
2332         }
2333 
2334         final int ch2 = input2.read();
2335         return ch2 == EOF;
2336     }
2337 
2338     /**
2339      * Compares the contents of two Readers to determine if they are equal or
2340      * not.
2341      * <p>
2342      * This method buffers the input internally using
2343      * <code>BufferedReader</code> if they are not already buffered.
2344      *
2345      * @param input1  the first reader
2346      * @param input2  the second reader
2347      * @return true if the content of the readers are equal or they both don't
2348      * exist, false otherwise
2349      * @throws NullPointerException if either input is null
2350      * @throws IOException if an I/O error occurs
2351      * @since 1.1
2352      */
2353     public static boolean contentEquals(Reader input1, Reader input2)
2354             throws IOException {
2355         if (input1 == input2) {
2356             return true;
2357         }
2358 
2359         input1 = toBufferedReader(input1);
2360         input2 = toBufferedReader(input2);
2361 
2362         int ch = input1.read();
2363         while (EOF != ch) {
2364             final int ch2 = input2.read();
2365             if (ch != ch2) {
2366                 return false;
2367             }
2368             ch = input1.read();
2369         }
2370 
2371         final int ch2 = input2.read();
2372         return ch2 == EOF;
2373     }
2374 
2375     /**
2376      * Compares the contents of two Readers to determine if they are equal or
2377      * not, ignoring EOL characters.
2378      * <p>
2379      * This method buffers the input internally using
2380      * <code>BufferedReader</code> if they are not already buffered.
2381      *
2382      * @param input1  the first reader
2383      * @param input2  the second reader
2384      * @return true if the content of the readers are equal (ignoring EOL differences),  false otherwise
2385      * @throws NullPointerException if either input is null
2386      * @throws IOException if an I/O error occurs
2387      * @since 2.2
2388      */
2389     public static boolean contentEqualsIgnoreEOL(final Reader input1, final Reader input2)
2390             throws IOException {
2391         if (input1 == input2) {
2392             return true;
2393         }
2394         final BufferedReader br1 = toBufferedReader(input1);
2395         final BufferedReader br2 = toBufferedReader(input2);
2396 
2397         String line1 = br1.readLine();
2398         String line2 = br2.readLine();
2399         while (line1 != null && line2 != null && line1.equals(line2)) {
2400             line1 = br1.readLine();
2401             line2 = br2.readLine();
2402         }
2403         return line1 == null ? line2 == null ? true : false : line1.equals(line2);
2404     }
2405 
2406     /**
2407      * Skips bytes from an input byte stream.
2408      * This implementation guarantees that it will read as many bytes
2409      * as possible before giving up; this may not always be the case for
2410      * skip() implementations in subclasses of {@link InputStream}.
2411      * <p>
2412      * Note that the implementation uses {@link InputStream#read(byte[], int, int)} rather
2413      * than delegating to {@link InputStream#skip(long)}.
2414      * This means that the method may be considerably less efficient than using the actual skip implementation,
2415      * this is done to guarantee that the correct number of bytes are skipped.
2416      * </p>
2417      *
2418      *
2419      * @param input byte stream to skip
2420      * @param toSkip number of bytes to skip.
2421      * @return number of bytes actually skipped.
2422      *
2423      * @see InputStream#skip(long)
2424      * @see <a href="https://issues.apache.org/jira/browse/IO-203">IO-203 - Add skipFully() method for InputStreams</a>
2425      *
2426      * @throws IOException if there is a problem reading the file
2427      * @throws IllegalArgumentException if toSkip is negative
2428      * @since 2.0
2429      */
2430     public static long skip(final InputStream input, final long toSkip) throws IOException {
2431         if (toSkip < 0) {
2432             throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip);
2433         }
2434         /*
2435          * N.B. no need to synchronize this because: - we don't care if the buffer is created multiple times (the data
2436          * is ignored) - we always use the same size buffer, so if it it is recreated it will still be OK (if the buffer
2437          * size were variable, we would need to synch. to ensure some other thread did not create a smaller one)
2438          */
2439         if (SKIP_BYTE_BUFFER == null) {
2440             SKIP_BYTE_BUFFER = new byte[SKIP_BUFFER_SIZE];
2441         }
2442         long remain = toSkip;
2443         while (remain > 0) {
2444             // See https://issues.apache.org/jira/browse/IO-203 for why we use read() rather than delegating to skip()
2445             final long n = input.read(SKIP_BYTE_BUFFER, 0, (int) Math.min(remain, SKIP_BUFFER_SIZE));
2446             if (n < 0) { // EOF
2447                 break;
2448             }
2449             remain -= n;
2450         }
2451         return toSkip - remain;
2452     }
2453 
2454     /**
2455      * Skips bytes from a ReadableByteChannel.
2456      * This implementation guarantees that it will read as many bytes
2457      * as possible before giving up.
2458      *
2459      * @param input ReadableByteChannel to skip
2460      * @param toSkip number of bytes to skip.
2461      * @return number of bytes actually skipped.
2462      *
2463      * @throws IOException if there is a problem reading the ReadableByteChannel
2464      * @throws IllegalArgumentException if toSkip is negative
2465      * @since 2.5
2466      */
2467     public static long skip(final ReadableByteChannel input, final long toSkip) throws IOException {
2468         if (toSkip < 0) {
2469             throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip);
2470         }
2471         final ByteBuffer skipByteBuffer = ByteBuffer.allocate((int) Math.min(toSkip, SKIP_BUFFER_SIZE));
2472         long remain = toSkip;
2473         while (remain > 0) {
2474             skipByteBuffer.position(0);
2475             skipByteBuffer.limit((int) Math.min(remain, SKIP_BUFFER_SIZE));
2476             final int n = input.read(skipByteBuffer);
2477             if (n == EOF) {
2478                 break;
2479             }
2480             remain -= n;
2481         }
2482         return toSkip - remain;
2483     }
2484 
2485     /**
2486      * Skips characters from an input character stream.
2487      * This implementation guarantees that it will read as many characters
2488      * as possible before giving up; this may not always be the case for
2489      * skip() implementations in subclasses of {@link Reader}.
2490      * <p>
2491      * Note that the implementation uses {@link Reader#read(char[], int, int)} rather
2492      * than delegating to {@link Reader#skip(long)}.
2493      * This means that the method may be considerably less efficient than using the actual skip implementation,
2494      * this is done to guarantee that the correct number of characters are skipped.
2495      * </p>
2496      *
2497      * @param input character stream to skip
2498      * @param toSkip number of characters to skip.
2499      * @return number of characters actually skipped.
2500      *
2501      * @see Reader#skip(long)
2502      * @see <a href="https://issues.apache.org/jira/browse/IO-203">IO-203 - Add skipFully() method for InputStreams</a>
2503      *
2504      * @throws IOException if there is a problem reading the file
2505      * @throws IllegalArgumentException if toSkip is negative
2506      * @since 2.0
2507      */
2508     public static long skip(final Reader input, final long toSkip) throws IOException {
2509         if (toSkip < 0) {
2510             throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip);
2511         }
2512         /*
2513          * N.B. no need to synchronize this because: - we don't care if the buffer is created multiple times (the data
2514          * is ignored) - we always use the same size buffer, so if it it is recreated it will still be OK (if the buffer
2515          * size were variable, we would need to synch. to ensure some other thread did not create a smaller one)
2516          */
2517         if (SKIP_CHAR_BUFFER == null) {
2518             SKIP_CHAR_BUFFER = new char[SKIP_BUFFER_SIZE];
2519         }
2520         long remain = toSkip;
2521         while (remain > 0) {
2522             // See https://issues.apache.org/jira/browse/IO-203 for why we use read() rather than delegating to skip()
2523             final long n = input.read(SKIP_CHAR_BUFFER, 0, (int) Math.min(remain, SKIP_BUFFER_SIZE));
2524             if (n < 0) { // EOF
2525                 break;
2526             }
2527             remain -= n;
2528         }
2529         return toSkip - remain;
2530     }
2531 
2532     /**
2533      * Skips the requested number of bytes or fail if there are not enough left.
2534      * <p>
2535      * This allows for the possibility that {@link InputStream#skip(long)} may
2536      * not skip as many bytes as requested (most likely because of reaching EOF).
2537      * <p>
2538      * Note that the implementation uses {@link #skip(InputStream, long)}.
2539      * This means that the method may be considerably less efficient than using the actual skip implementation,
2540      * this is done to guarantee that the correct number of characters are skipped.
2541      * </p>
2542      *
2543      * @param input stream to skip
2544      * @param toSkip the number of bytes to skip
2545      * @see InputStream#skip(long)
2546      *
2547      * @throws IOException if there is a problem reading the file
2548      * @throws IllegalArgumentException if toSkip is negative
2549      * @throws EOFException if the number of bytes skipped was incorrect
2550      * @since 2.0
2551      */
2552     public static void skipFully(final InputStream input, final long toSkip) throws IOException {
2553         if (toSkip < 0) {
2554             throw new IllegalArgumentException("Bytes to skip must not be negative: " + toSkip);
2555         }
2556         final long skipped = skip(input, toSkip);
2557         if (skipped != toSkip) {
2558             throw new EOFException("Bytes to skip: " + toSkip + " actual: " + skipped);
2559         }
2560     }
2561 
2562     /**
2563      * Skips the requested number of bytes or fail if there are not enough left.
2564      *
2565      * @param input ReadableByteChannel to skip
2566      * @param toSkip the number of bytes to skip
2567      *
2568      * @throws IOException if there is a problem reading the ReadableByteChannel
2569      * @throws IllegalArgumentException if toSkip is negative
2570      * @throws EOFException if the number of bytes skipped was incorrect
2571      * @since 2.5
2572      */
2573     public static void skipFully(final ReadableByteChannel input, final long toSkip) throws IOException {
2574         if (toSkip < 0) {
2575             throw new IllegalArgumentException("Bytes to skip must not be negative: " + toSkip);
2576         }
2577         final long skipped = skip(input, toSkip);
2578         if (skipped != toSkip) {
2579             throw new EOFException("Bytes to skip: " + toSkip + " actual: " + skipped);
2580         }
2581     }
2582 
2583     /**
2584      * Skips the requested number of characters or fail if there are not enough left.
2585      * <p>
2586      * This allows for the possibility that {@link Reader#skip(long)} may
2587      * not skip as many characters as requested (most likely because of reaching EOF).
2588      * <p>
2589      * Note that the implementation uses {@link #skip(Reader, long)}.
2590      * This means that the method may be considerably less efficient than using the actual skip implementation,
2591      * this is done to guarantee that the correct number of characters are skipped.
2592      * </p>
2593      *
2594      * @param input stream to skip
2595      * @param toSkip the number of characters to skip
2596      * @see Reader#skip(long)
2597      *
2598      * @throws IOException if there is a problem reading the file
2599      * @throws IllegalArgumentException if toSkip is negative
2600      * @throws EOFException if the number of characters skipped was incorrect
2601      * @since 2.0
2602      */
2603     public static void skipFully(final Reader input, final long toSkip) throws IOException {
2604         final long skipped = skip(input, toSkip);
2605         if (skipped != toSkip) {
2606             throw new EOFException("Chars to skip: " + toSkip + " actual: " + skipped);
2607         }
2608     }
2609 
2610 
2611     /**
2612      * Reads characters from an input character stream.
2613      * This implementation guarantees that it will read as many characters
2614      * as possible before giving up; this may not always be the case for
2615      * subclasses of {@link Reader}.
2616      *
2617      * @param input where to read input from
2618      * @param buffer destination
2619      * @param offset initial offset into buffer
2620      * @param length length to read, must be >= 0
2621      * @return actual length read; may be less than requested if EOF was reached
2622      * @throws IOException if a read error occurs
2623      * @since 2.2
2624      */
2625     public static int read(final Reader input, final char[] buffer, final int offset, final int length) throws IOException {
2626         if (length < 0) {
2627             throw new IllegalArgumentException("Length must not be negative: " + length);
2628         }
2629         int remaining = length;
2630         while (remaining > 0) {
2631             final int location = length - remaining;
2632             final int count = input.read(buffer, offset + location, remaining);
2633             if (EOF == count) { // EOF
2634                 break;
2635             }
2636             remaining -= count;
2637         }
2638         return length - remaining;
2639     }
2640 
2641     /**
2642      * Reads characters from an input character stream.
2643      * This implementation guarantees that it will read as many characters
2644      * as possible before giving up; this may not always be the case for
2645      * subclasses of {@link Reader}.
2646      *
2647      * @param input where to read input from
2648      * @param buffer destination
2649      * @return actual length read; may be less than requested if EOF was reached
2650      * @throws IOException if a read error occurs
2651      * @since 2.2
2652      */
2653     public static int read(final Reader input, final char[] buffer) throws IOException {
2654         return read(input, buffer, 0, buffer.length);
2655     }
2656 
2657     /**
2658      * Reads bytes from an input stream.
2659      * This implementation guarantees that it will read as many bytes
2660      * as possible before giving up; this may not always be the case for
2661      * subclasses of {@link InputStream}.
2662      *
2663      * @param input where to read input from
2664      * @param buffer destination
2665      * @param offset initial offset into buffer
2666      * @param length length to read, must be >= 0
2667      * @return actual length read; may be less than requested if EOF was reached
2668      * @throws IOException if a read error occurs
2669      * @since 2.2
2670      */
2671     public static int read(final InputStream input, final byte[] buffer, final int offset, final int length) throws IOException {
2672         if (length < 0) {
2673             throw new IllegalArgumentException("Length must not be negative: " + length);
2674         }
2675         int remaining = length;
2676         while (remaining > 0) {
2677             final int location = length - remaining;
2678             final int count = input.read(buffer, offset + location, remaining);
2679             if (EOF == count) { // EOF
2680                 break;
2681             }
2682             remaining -= count;
2683         }
2684         return length - remaining;
2685     }
2686 
2687     /**
2688      * Reads bytes from an input stream.
2689      * This implementation guarantees that it will read as many bytes
2690      * as possible before giving up; this may not always be the case for
2691      * subclasses of {@link InputStream}.
2692      *
2693      * @param input where to read input from
2694      * @param buffer destination
2695      * @return actual length read; may be less than requested if EOF was reached
2696      * @throws IOException if a read error occurs
2697      * @since 2.2
2698      */
2699     public static int read(final InputStream input, final byte[] buffer) throws IOException {
2700         return read(input, buffer, 0, buffer.length);
2701     }
2702 
2703     /**
2704      * Reads bytes from a ReadableByteChannel.
2705      * <p>
2706      * This implementation guarantees that it will read as many bytes
2707      * as possible before giving up; this may not always be the case for
2708      * subclasses of {@link ReadableByteChannel}.
2709      *
2710      * @param input the byte channel to read
2711      * @param buffer byte buffer destination
2712      * @return the actual length read; may be less than requested if EOF was reached
2713      * @throws IOException if a read error occurs
2714      * @since 2.5
2715      */
2716     public static int read(final ReadableByteChannel input, final ByteBuffer buffer) throws IOException {
2717         final int length = buffer.remaining();
2718         while (buffer.remaining() > 0) {
2719             final int count = input.read(buffer);
2720             if (EOF == count) { // EOF
2721                 break;
2722             }
2723         }
2724         return length - buffer.remaining();
2725     }
2726 
2727     /**
2728      * Reads the requested number of characters or fail if there are not enough left.
2729      * <p>
2730      * This allows for the possibility that {@link Reader#read(char[], int, int)} may
2731      * not read as many characters as requested (most likely because of reaching EOF).
2732      *
2733      * @param input where to read input from
2734      * @param buffer destination
2735      * @param offset initial offset into buffer
2736      * @param length length to read, must be >= 0
2737      *
2738      * @throws IOException if there is a problem reading the file
2739      * @throws IllegalArgumentException if length is negative
2740      * @throws EOFException if the number of characters read was incorrect
2741      * @since 2.2
2742      */
2743     public static void readFully(final Reader input, final char[] buffer, final int offset, final int length) throws IOException {
2744         final int actual = read(input, buffer, offset, length);
2745         if (actual != length) {
2746             throw new EOFException("Length to read: " + length + " actual: " + actual);
2747         }
2748     }
2749 
2750     /**
2751      * Reads the requested number of characters or fail if there are not enough left.
2752      * <p>
2753      * This allows for the possibility that {@link Reader#read(char[], int, int)} may
2754      * not read as many characters as requested (most likely because of reaching EOF).
2755      *
2756      * @param input where to read input from
2757      * @param buffer destination
2758      *
2759      * @throws IOException if there is a problem reading the file
2760      * @throws IllegalArgumentException if length is negative
2761      * @throws EOFException if the number of characters read was incorrect
2762      * @since 2.2
2763      */
2764     public static void readFully(final Reader input, final char[] buffer) throws IOException {
2765         readFully(input, buffer, 0, buffer.length);
2766     }
2767 
2768     /**
2769      * Reads the requested number of bytes or fail if there are not enough left.
2770      * <p>
2771      * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may
2772      * not read as many bytes as requested (most likely because of reaching EOF).
2773      *
2774      * @param input where to read input from
2775      * @param buffer destination
2776      * @param offset initial offset into buffer
2777      * @param length length to read, must be >= 0
2778      *
2779      * @throws IOException if there is a problem reading the file
2780      * @throws IllegalArgumentException if length is negative
2781      * @throws EOFException if the number of bytes read was incorrect
2782      * @since 2.2
2783      */
2784     public static void readFully(final InputStream input, final byte[] buffer, final int offset, final int length) throws IOException {
2785         final int actual = read(input, buffer, offset, length);
2786         if (actual != length) {
2787             throw new EOFException("Length to read: " + length + " actual: " + actual);
2788         }
2789     }
2790 
2791     /**
2792      * Reads the requested number of bytes or fail if there are not enough left.
2793      * <p>
2794      * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may
2795      * not read as many bytes as requested (most likely because of reaching EOF).
2796      *
2797      * @param input where to read input from
2798      * @param buffer destination
2799      *
2800      * @throws IOException if there is a problem reading the file
2801      * @throws IllegalArgumentException if length is negative
2802      * @throws EOFException if the number of bytes read was incorrect
2803      * @since 2.2
2804      */
2805     public static void readFully(final InputStream input, final byte[] buffer) throws IOException {
2806         readFully(input, buffer, 0, buffer.length);
2807     }
2808 
2809     /**
2810      * Reads the requested number of bytes or fail if there are not enough left.
2811      * <p>
2812      * This allows for the possibility that {@link ReadableByteChannel#read(ByteBuffer)} may
2813      * not read as many bytes as requested (most likely because of reaching EOF).
2814      *
2815      * @param input the byte channel to read
2816      * @param buffer byte buffer destination
2817      *
2818      * @throws IOException if there is a problem reading the file
2819      * @throws EOFException if the number of bytes read was incorrect
2820      * @since 2.5
2821      */
2822     public static void readFully(final ReadableByteChannel input, final ByteBuffer buffer) throws IOException {
2823         final int expected = buffer.remaining();
2824         final int actual = read(input, buffer);
2825         if (actual != expected) {
2826             throw new EOFException("Length to read: " + expected + " actual: " + actual);
2827         }
2828     }
2829 }