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