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