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