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