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