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