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