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