    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 2.5 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="http://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 thrown instead of {@link java.io
    1179     *                                                      .UnsupportedEncodingException} in version 2.2 if the
    1180     *                                                      encoding is not supported.
    1181     * @since 1.1
    1182     */
    1183    public static void copy(final InputStream input, final Writer writer, final String inputCharsetName)
    1184            throws IOException {
    1185        copy(input, writer, Charsets.toCharset(inputCharsetName));
    1186    }
    1187
    1188    /**
    1189     * Copies bytes from a {@link java.io.ByteArrayOutputStream} to a {@link QueueInputStream}.
    1190     * <p>
    1191     * Unlike using JDK {@link java.io.PipedInputStream} and {@link java.io.PipedOutputStream} for this, this
    1192     * solution works safely in a single thread environment.
    1193     * </p>
    1194     * <p>
    1195     * Example usage:
    1196     * </p>
    1197     *
    1198     * <pre>
    1199     * ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    1200     * outputStream.writeBytes("hello world".getBytes(StandardCharsets.UTF_8));
    1201     *
    1202     * InputStream inputStream = IOUtils.copy(outputStream);
    1203     * </pre>
    1204     *
    1205     * @param outputStream the {@link java.io.ByteArrayOutputStream} to read.
    1206     * @return the {@link QueueInputStream} filled with the content of the outputStream.
    1207     * @throws NullPointerException if the {@link java.io.ByteArrayOutputStream} is {@code null}.
    1208     * @throws IOException if an I/O error occurs.
    1209     * @since 2.12
    1210     */
    1211    @SuppressWarnings("resource") // streams are closed by the caller.
    1212    public static QueueInputStream copy(final java.io.ByteArrayOutputStream outputStream) throws IOException {
    1213        Objects.requireNonNull(outputStream, "outputStream");
    1214        final QueueInputStream in = new QueueInputStream();
    1215        outputStream.writeTo(in.newQueueOutputStream());
    1216        return in;
    1217    }
    1218
    1219    /**
    1220     * Copies chars from a {@link Reader} to a {@link Appendable}.
    1221     * <p>
    1222     * This method buffers the input internally, so there is no need to use a
    1223     * {@link BufferedReader}.
    1224     * </p>
    1225     * <p>
    1226     * Large streams (over 2GB) will return a chars copied value of
    1227     * {@code -1} after the copy has completed since the correct
    1228     * number of chars cannot be returned as an int. For large streams
    1229     * use the {@link #copyLarge(Reader, Writer)} method.
    1230     * </p>
    1231     *
    1232     * @param reader the {@link Reader} to read
    1233     * @param output the {@link Appendable} to write to
    1234     * @return the number of characters copied, or -1 if &gt; Integer.MAX_VALUE
    1235     * @throws NullPointerException if the input or output is null
    1236     * @throws IOException          if an I/O error occurs
    1237     * @since 2.7
    1238     */
    1239    public static long copy(final Reader reader, final Appendable output) throws IOException {
    1240        return copy(reader, output, CharBuffer.allocate(DEFAULT_BUFFER_SIZE));
    1241    }
    1242
    1243    /**
    1244     * Copies chars from a {@link Reader} to an {@link Appendable}.
    1245     * <p>
    1246     * This method uses the provided buffer, so there is no need to use a
    1247     * {@link BufferedReader}.
    1248     * </p>
    1249     *
    1250     * @param reader the {@link Reader} to read
    1251     * @param output the {@link Appendable} to write to
    1252     * @param buffer the buffer to be used for the copy
    1253     * @return the number of characters copied
    1254     * @throws NullPointerException if the input or output is null
    1255     * @throws IOException          if an I/O error occurs
    1256     * @since 2.7
    1257     */
    1258    public static long copy(final Reader reader, final Appendable output, final CharBuffer buffer) throws IOException {
    1259        long count = 0;
    1260        int n;
    1261        while (EOF != (n = reader.read(buffer))) {
    1262            buffer.flip();
    1263            output.append(buffer, 0, n);
    1264            count += n;
    1265        }
    1266        return count;
    1267    }
    1268
    1269    /**
    1270     * Copies chars from a {@link Reader} to bytes on an
    1271     * {@link OutputStream} using the default character encoding of the
    1272     * platform, and calling flush.
    1273     * <p>
    1274     * This method buffers the input internally, so there is no need to use a
    1275     * {@link BufferedReader}.
    1276     * </p>
    1277     * <p>
    1278     * Due to the implementation of OutputStreamWriter, this method performs a
    1279     * flush.
    1280     * </p>
    1281     * <p>
    1282     * This method uses {@link OutputStreamWriter}.
    1283     * </p>
    1284     *
    1285     * @param reader the {@link Reader} to read
    1286     * @param output the {@link OutputStream} to write to
    1287     * @throws NullPointerException if the input or output is null
    1288     * @throws IOException          if an I/O error occurs
    1289     * @since 1.1
    1290     * @deprecated 2.5 use {@link #copy(Reader, OutputStream, Charset)} instead
    1291     */
    1292    @Deprecated
    1293    public static void copy(final Reader reader, final OutputStream output)
    1294            throws IOException {
    1295        copy(reader, output, Charset.defaultCharset());
    1296    }
    1297
    1298    /**
    1299     * Copies chars from a {@link Reader} to bytes on an
    1300     * {@link OutputStream} using the specified character encoding, and
    1301     * calling flush.
    1302     * <p>
    1303     * This method buffers the input internally, so there is no need to use a
    1304     * {@link BufferedReader}.
    1305     * </p>
    1306     * <p>
    1307     * Due to the implementation of OutputStreamWriter, this method performs a
    1308     * flush.
    1309     * </p>
    1310     * <p>
    1311     * This method uses {@link OutputStreamWriter}.
    1312     * </p>
    1313     *
    1314     * @param reader the {@link Reader} to read
    1315     * @param output the {@link OutputStream} to write to
    1316     * @param outputCharset the charset to use for the OutputStream, null means platform default
    1317     * @throws NullPointerException if the input or output is null
    1318     * @throws IOException          if an I/O error occurs
    1319     * @since 2.3
    1320     */
    1321    public static void copy(final Reader reader, final OutputStream output, final Charset outputCharset)
    1322            throws IOException {
    1323        final OutputStreamWriter writer = new OutputStreamWriter(output, Charsets.toCharset(outputCharset));
    1324        copy(reader, writer);
    1325        // XXX Unless anyone is planning on rewriting OutputStreamWriter,
    1326        // we have to flush here.
    1327        writer.flush();
    1328    }
    1329
    1330    /**
    1331     * Copies chars from a {@link Reader} to bytes on an
    1332     * {@link OutputStream} using the specified character encoding, and
    1333     * calling flush.
    1334     * <p>
    1335     * This method buffers the input internally, so there is no need to use a
    1336     * {@link BufferedReader}.
    1337     * </p>
    1338     * <p>
    1339     * Character encoding names can be found at
    1340     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    1341     * </p>
    1342     * <p>
    1343     * Due to the implementation of OutputStreamWriter, this method performs a
    1344     * flush.
    1345     * </p>
    1346     * <p>
    1347     * This method uses {@link OutputStreamWriter}.
    1348     * </p>
    1349     *
    1350     * @param reader the {@link Reader} to read
    1351     * @param output the {@link OutputStream} to write to
    1352     * @param outputCharsetName the name of the requested charset for the OutputStream, null means platform default
    1353     * @throws NullPointerException                         if the input or output is null
    1354     * @throws IOException                                  if an I/O error occurs
    1355     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
    1356     *                                                      .UnsupportedEncodingException} in version 2.2 if the
    1357     *                                                      encoding is not supported.
    1358     * @since 1.1
    1359     */
    1360    public static void copy(final Reader reader, final OutputStream output, final String outputCharsetName)
    1361            throws IOException {
    1362        copy(reader, output, Charsets.toCharset(outputCharsetName));
    1363    }
    1364
    1365    /**
    1366     * Copies chars from a {@link Reader} to a {@link Writer}.
    1367     * <p>
    1368     * This method buffers the input internally, so there is no need to use a
    1369     * {@link BufferedReader}.
    1370     * </p>
    1371     * <p>
    1372     * Large streams (over 2GB) will return a chars copied value of
    1373     * {@code -1} after the copy has completed since the correct
    1374     * number of chars cannot be returned as an int. For large streams
    1375     * use the {@link #copyLarge(Reader, Writer)} method.
    1376     * </p>
    1377     *
    1378     * @param reader the {@link Reader} to read.
    1379     * @param writer the {@link Writer} to write.
    1380     * @return the number of characters copied, or -1 if &gt; Integer.MAX_VALUE
    1381     * @throws NullPointerException if the input or output is null
    1382     * @throws IOException          if an I/O error occurs
    1383     * @since 1.1
    1384     */
    1385    public static int copy(final Reader reader, final Writer writer) throws IOException {
    1386        final long count = copyLarge(reader, writer);
    1387        if (count > Integer.MAX_VALUE) {
    1388            return EOF;
    1389        }
    1390        return (int) count;
    1391    }
    1392
    1393    /**
    1394     * Copies bytes from a {@link URL} to an {@link OutputStream}.
    1395     * <p>
    1396     * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}.
    1397     * </p>
    1398     * <p>
    1399     * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
    1400     * </p>
    1401     *
    1402     * @param url the {@link URL} to read.
    1403     * @param file the {@link OutputStream} to write.
    1404     * @return the number of bytes copied.
    1405     * @throws NullPointerException if the URL is {@code null}.
    1406     * @throws NullPointerException if the OutputStream is {@code null}.
    1407     * @throws IOException if an I/O error occurs.
    1408     * @since 2.9.0
    1409     */
    1410    public static long copy(final URL url, final File file) throws IOException {
    1411        try (OutputStream outputStream = Files.newOutputStream(Objects.requireNonNull(file, "file").toPath())) {
    1412            return copy(url, outputStream);
    1413        }
    1414    }
    1415
    1416    /**
    1417     * Copies bytes from a {@link URL} to an {@link OutputStream}.
    1418     * <p>
    1419     * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}.
    1420     * </p>
    1421     * <p>
    1422     * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
    1423     * </p>
    1424     *
    1425     * @param url the {@link URL} to read.
    1426     * @param outputStream the {@link OutputStream} to write.
    1427     * @return the number of bytes copied.
    1428     * @throws NullPointerException if the URL is {@code null}.
    1429     * @throws NullPointerException if the OutputStream is {@code null}.
    1430     * @throws IOException if an I/O error occurs.
    1431     * @since 2.9.0
    1432     */
    1433    public static long copy(final URL url, final OutputStream outputStream) throws IOException {
    1434        try (InputStream inputStream = Objects.requireNonNull(url, "url").openStream()) {
    1435            return copyLarge(inputStream, outputStream);
    1436        }
    1437    }
    1438
    1439    /**
    1440     * Copies bytes from a large (over 2GB) {@link InputStream} to an
    1441     * {@link OutputStream}.
    1442     * <p>
    1443     * This method buffers the input internally, so there is no need to use a
    1444     * {@link BufferedInputStream}.
    1445     * </p>
    1446     * <p>
    1447     * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
    1448     * </p>
    1449     *
    1450     * @param inputStream the {@link InputStream} to read.
    1451     * @param outputStream the {@link OutputStream} to write.
    1452     * @return the number of bytes copied.
    1453     * @throws NullPointerException if the InputStream is {@code null}.
    1454     * @throws NullPointerException if the OutputStream is {@code null}.
    1455     * @throws IOException if an I/O error occurs.
    1456     * @since 1.3
    1457     */
    1458    public static long copyLarge(final InputStream inputStream, final OutputStream outputStream)
    1459            throws IOException {
    1460        return copy(inputStream, outputStream, DEFAULT_BUFFER_SIZE);
    1461    }
    1462
    1463    /**
    1464     * Copies bytes from a large (over 2GB) {@link InputStream} to an
    1465     * {@link OutputStream}.
    1466     * <p>
    1467     * This method uses the provided buffer, so there is no need to use a
    1468     * {@link BufferedInputStream}.
    1469     * </p>
    1470     *
    1471     * @param inputStream the {@link InputStream} to read.
    1472     * @param outputStream the {@link OutputStream} to write.
    1473     * @param buffer the buffer to use for the copy
    1474     * @return the number of bytes copied.
    1475     * @throws NullPointerException if the InputStream is {@code null}.
    1476     * @throws NullPointerException if the OutputStream is {@code null}.
    1477     * @throws IOException if an I/O error occurs.
    1478     * @since 2.2
    1479     */
    1480    @SuppressWarnings("resource") // streams are closed by the caller.
    1481    public static long copyLarge(final InputStream inputStream, final OutputStream outputStream, final byte[] buffer)
    1482        throws IOException {
    1483        Objects.requireNonNull(inputStream, "inputStream");
    1484        Objects.requireNonNull(outputStream, "outputStream");
    1485        long count = 0;
    1486        int n;
    1487        while (EOF != (n = inputStream.read(buffer))) {
    1488            outputStream.write(buffer, 0, n);
    1489            count += n;
    1490        }
    1491        return count;
    1492    }
    1493
    1494    /**
    1495     * Copies some or all bytes from a large (over 2GB) {@link InputStream} to an
    1496     * {@link OutputStream}, optionally skipping input bytes.
    1497     * <p>
    1498     * This method buffers the input internally, so there is no need to use a
    1499     * {@link BufferedInputStream}.
    1500     * </p>
    1501     * <p>
    1502     * Note that the implementation uses {@link #skip(InputStream, long)}.
    1503     * This means that the method may be considerably less efficient than using the actual skip implementation,
    1504     * this is done to guarantee that the correct number of characters are skipped.
    1505     * </p>
    1506     * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
    1507     *
    1508     * @param input the {@link InputStream} to read
    1509     * @param output the {@link OutputStream} to write to
    1510     * @param inputOffset : number of bytes to skip from input before copying
    1511     * -ve values are ignored
    1512     * @param length : number of bytes to copy. -ve means all
    1513     * @return the number of bytes copied
    1514     * @throws NullPointerException if the input or output is null
    1515     * @throws IOException          if an I/O error occurs
    1516     * @since 2.2
    1517     */
    1518    public static long copyLarge(final InputStream input, final OutputStream output, final long inputOffset,
    1519                                 final long length) throws IOException {
    1520        return copyLarge(input, output, inputOffset, length, getScratchByteArray());
    1521    }
    1522
    1523    /**
    1524     * Copies some or all bytes from a large (over 2GB) {@link InputStream} to an
    1525     * {@link OutputStream}, optionally skipping input bytes.
    1526     * <p>
    1527     * This method uses the provided buffer, so there is no need to use a
    1528     * {@link BufferedInputStream}.
    1529     * </p>
    1530     * <p>
    1531     * Note that the implementation uses {@link #skip(InputStream, long)}.
    1532     * This means that the method may be considerably less efficient than using the actual skip implementation,
    1533     * this is done to guarantee that the correct number of characters are skipped.
    1534     * </p>
    1535     *
    1536     * @param input the {@link InputStream} to read
    1537     * @param output the {@link OutputStream} to write to
    1538     * @param inputOffset : number of bytes to skip from input before copying
    1539     * -ve values are ignored
    1540     * @param length : number of bytes to copy. -ve means all
    1541     * @param buffer the buffer to use for the copy
    1542     * @return the number of bytes copied
    1543     * @throws NullPointerException if the input or output is null
    1544     * @throws IOException          if an I/O error occurs
    1545     * @since 2.2
    1546     */
    1547    public static long copyLarge(final InputStream input, final OutputStream output,
    1548                                 final long inputOffset, final long length, final byte[] buffer) throws IOException {
    1549        if (inputOffset > 0) {
    1550            skipFully(input, inputOffset);
    1551        }
    1552        if (length == 0) {
    1553            return 0;
    1554        }
    1555        final int bufferLength = buffer.length;
    1556        int bytesToRead = bufferLength;
    1557        if (length > 0 && length < bufferLength) {
    1558            bytesToRead = (int) length;
    1559        }
    1560        int read;
    1561        long totalRead = 0;
    1562        while (bytesToRead > 0 && EOF != (read = input.read(buffer, 0, bytesToRead))) {
    1563            output.write(buffer, 0, read);
    1564            totalRead += read;
    1565            if (length > 0) { // only adjust length if not reading to the end
    1566                // Note the cast must work because buffer.length is an integer
    1567                bytesToRead = (int) Math.min(length - totalRead, bufferLength);
    1568            }
    1569        }
    1570        return totalRead;
    1571    }
    1572
    1573    /**
    1574     * Copies chars from a large (over 2GB) {@link Reader} to a {@link Writer}.
    1575     * <p>
    1576     * This method buffers the input internally, so there is no need to use a
    1577     * {@link BufferedReader}.
    1578     * </p>
    1579     * <p>
    1580     * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
    1581     * </p>
    1582     *
    1583     * @param reader the {@link Reader} to source.
    1584     * @param writer the {@link Writer} to target.
    1585     * @return the number of characters copied
    1586     * @throws NullPointerException if the input or output is null
    1587     * @throws IOException          if an I/O error occurs
    1588     * @since 1.3
    1589     */
    1590    public static long copyLarge(final Reader reader, final Writer writer) throws IOException {
    1591        return copyLarge(reader, writer, getScratchCharArray());
    1592    }
    1593
    1594    /**
    1595     * Copies chars from a large (over 2GB) {@link Reader} to a {@link Writer}.
    1596     * <p>
    1597     * This method uses the provided buffer, so there is no need to use a
    1598     * {@link BufferedReader}.
    1599     * </p>
    1600     *
    1601     * @param reader the {@link Reader} to source.
    1602     * @param writer the {@link Writer} to target.
    1603     * @param buffer the buffer to be used for the copy
    1604     * @return the number of characters copied
    1605     * @throws NullPointerException if the input or output is null
    1606     * @throws IOException          if an I/O error occurs
    1607     * @since 2.2
    1608     */
    1609    public static long copyLarge(final Reader reader, final Writer writer, final char[] buffer) throws IOException {
    1610        long count = 0;
    1611        int n;
    1612        while (EOF != (n = reader.read(buffer))) {
    1613            writer.write(buffer, 0, n);
    1614            count += n;
    1615        }
    1616        return count;
    1617    }
    1618
    1619    /**
    1620     * Copies some or all chars from a large (over 2GB) {@link InputStream} to an
    1621     * {@link OutputStream}, optionally skipping input chars.
    1622     * <p>
    1623     * This method buffers the input internally, so there is no need to use a
    1624     * {@link BufferedReader}.
    1625     * </p>
    1626     * <p>
    1627     * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
    1628     * </p>
    1629     *
    1630     * @param reader the {@link Reader} to read
    1631     * @param writer the {@link Writer} to write to
    1632     * @param inputOffset : number of chars to skip from input before copying
    1633     * -ve values are ignored
    1634     * @param length : number of chars to copy. -ve means all
    1635     * @return the number of chars copied
    1636     * @throws NullPointerException if the input or output is null
    1637     * @throws IOException          if an I/O error occurs
    1638     * @since 2.2
    1639     */
    1640    public static long copyLarge(final Reader reader, final Writer writer, final long inputOffset, final long length)
    1641            throws IOException {
    1642        return copyLarge(reader, writer, inputOffset, length, getScratchCharArray());
    1643    }
    1644
    1645    /**
    1646     * Copies some or all chars from a large (over 2GB) {@link InputStream} to an
    1647     * {@link OutputStream}, optionally skipping input chars.
    1648     * <p>
    1649     * This method uses the provided buffer, so there is no need to use a
    1650     * {@link BufferedReader}.
    1651     * </p>
    1652     *
    1653     * @param reader the {@link Reader} to read
    1654     * @param writer the {@link Writer} to write to
    1655     * @param inputOffset : number of chars to skip from input before copying
    1656     * -ve values are ignored
    1657     * @param length : number of chars to copy. -ve means all
    1658     * @param buffer the buffer to be used for the copy
    1659     * @return the number of chars copied
    1660     * @throws NullPointerException if the input or output is null
    1661     * @throws IOException          if an I/O error occurs
    1662     * @since 2.2
    1663     */
    1664    public static long copyLarge(final Reader reader, final Writer writer, final long inputOffset, final long length,
    1665                                 final char[] buffer)
    1666            throws IOException {
    1667        if (inputOffset > 0) {
    1668            skipFully(reader, inputOffset);
    1669        }
    1670        if (length == 0) {
    1671            return 0;
    1672        }
    1673        int bytesToRead = buffer.length;
    1674        if (length > 0 && length < buffer.length) {
    1675            bytesToRead = (int) length;
    1676        }
    1677        int read;
    1678        long totalRead = 0;
    1679        while (bytesToRead > 0 && EOF != (read = reader.read(buffer, 0, bytesToRead))) {
    1680            writer.write(buffer, 0, read);
    1681            totalRead += read;
    1682            if (length > 0) { // only adjust length if not reading to the end
    1683                // Note the cast must work because buffer.length is an integer
    1684                bytesToRead = (int) Math.min(length - totalRead, buffer.length);
    1685            }
    1686        }
    1687        return totalRead;
    1688    }
    1689
    1690    /**
    1691     * Fills the given array with 0s.
    1692     *
    1693     * @param arr The array to fill.
    1694     * @return The given array.
    1695     */
    1696    private static byte[] fill0(final byte[] arr) {
    1697        Arrays.fill(arr, (byte) 0);
    1698        return arr;
    1699    }
    1700
    1701    /**
    1702     * Fills the given array with 0s.
    1703     *
    1704     * @param arr The array to fill.
    1705     * @return The given array.
    1706     */
    1707    private static char[] fill0(final char[] arr) {
    1708        Arrays.fill(arr, (char) 0);
    1709        return arr;
    1710    }
    1711
    1712    /**
    1713     * Gets the internal byte array buffer, intended for both reading and writing.
    1714     *
    1715     * @return the internal byte array buffer, intended for both reading and writing.
    1716     */
    1717    static byte[] getScratchByteArray() {
    1718        return fill0(SCRATCH_BYTE_BUFFER_RW.get());
    1719    }
    1720
    1721    /**
    1722     * Gets the internal byte array intended for write only operations.
    1723     *
    1724     * @return the internal byte array intended for write only operations.
    1725     */
    1726    static byte[] getScratchByteArrayWriteOnly() {
    1727        return fill0(SCRATCH_BYTE_BUFFER_WO);
    1728    }
    1729
    1730    /**
    1731     * Gets the char byte array buffer, intended for both reading and writing.
    1732     *
    1733     * @return the char byte array buffer, intended for both reading and writing.
    1734     */
    1735    static char[] getScratchCharArray() {
    1736        return fill0(SCRATCH_CHAR_BUFFER_RW.get());
    1737    }
    1738
    1739    /**
    1740     * Gets the internal char array intended for write only operations.
    1741     *
    1742     * @return the internal char array intended for write only operations.
    1743     */
    1744    static char[] getScratchCharArrayWriteOnly() {
    1745        return fill0(SCRATCH_CHAR_BUFFER_WO);
    1746    }
    1747
    1748    /**
    1749     * Returns the length of the given array in a null-safe manner.
    1750     *
    1751     * @param array an array or null
    1752     * @return the array length -- or 0 if the given array is null.
    1753     * @since 2.7
    1754     */
    1755    public static int length(final byte[] array) {
    1756        return array == null ? 0 : array.length;
    1757    }
    1758
    1759    /**
    1760     * Returns the length of the given array in a null-safe manner.
    1761     *
    1762     * @param array an array or null
    1763     * @return the array length -- or 0 if the given array is null.
    1764     * @since 2.7
    1765     */
    1766    public static int length(final char[] array) {
    1767        return array == null ? 0 : array.length;
    1768    }
    1769
    1770    /**
    1771     * Returns the length of the given CharSequence in a null-safe manner.
    1772     *
    1773     * @param csq a CharSequence or null
    1774     * @return the CharSequence length -- or 0 if the given CharSequence is null.
    1775     * @since 2.7
    1776     */
    1777    public static int length(final CharSequence csq) {
    1778        return csq == null ? 0 : csq.length();
    1779    }
    1780
    1781    /**
    1782     * Returns the length of the given array in a null-safe manner.
    1783     *
    1784     * @param array an array or null
    1785     * @return the array length -- or 0 if the given array is null.
    1786     * @since 2.7
    1787     */
    1788    public static int length(final Object[] array) {
    1789        return array == null ? 0 : array.length;
    1790    }
    1791
    1792    /**
    1793     * Returns an Iterator for the lines in an {@link InputStream}, using
    1794     * the character encoding specified (or default encoding if null).
    1795     * <p>
    1796     * {@link LineIterator} holds a reference to the open
    1797     * {@link InputStream} specified here. When you have finished with
    1798     * the iterator you should close the stream to free internal resources.
    1799     * This can be done by using a try-with-resources block, closing the stream directly, or by calling
    1800     * {@link LineIterator#close()}.
    1801     * </p>
    1802     * <p>
    1803     * The recommended usage pattern is:
    1804     * </p>
    1805     * <pre>
    1806     * try {
    1807     *   LineIterator it = IOUtils.lineIterator(stream, charset);
    1808     *   while (it.hasNext()) {
    1809     *     String line = it.nextLine();
    1810     *     /// do something with line
    1811     *   }
    1812     * } finally {
    1813     *   IOUtils.closeQuietly(stream);
    1814     * }
    1815     * </pre>
    1816     *
    1817     * @param input the {@link InputStream} to read, not null
    1818     * @param charset the charset to use, null means platform default
    1819     * @return an Iterator of the lines in the reader, never null
    1820     * @throws IllegalArgumentException if the input is null
    1821     * @since 2.3
    1822     */
    1823    public static LineIterator lineIterator(final InputStream input, final Charset charset) {
    1824        return new LineIterator(new InputStreamReader(input, Charsets.toCharset(charset)));
    1825    }
    1826
    1827    /**
    1828     * Returns an Iterator for the lines in an {@link InputStream}, using
    1829     * the character encoding specified (or default encoding if null).
    1830     * <p>
    1831     * {@link LineIterator} holds a reference to the open
    1832     * {@link InputStream} specified here. When you have finished with
    1833     * the iterator you should close the stream to free internal resources.
    1834     * This can be done by using a try-with-resources block, closing the stream directly, or by calling
    1835     * {@link LineIterator#close()}.
    1836     * </p>
    1837     * <p>
    1838     * The recommended usage pattern is:
    1839     * </p>
    1840     * <pre>
    1841     * try {
    1842     *   LineIterator it = IOUtils.lineIterator(stream, StandardCharsets.UTF_8.name());
    1843     *   while (it.hasNext()) {
    1844     *     String line = it.nextLine();
    1845     *     /// do something with line
    1846     *   }
    1847     * } finally {
    1848     *   IOUtils.closeQuietly(stream);
    1849     * }
    1850     * </pre>
    1851     *
    1852     * @param input the {@link InputStream} to read, not null
    1853     * @param charsetName the encoding to use, null means platform default
    1854     * @return an Iterator of the lines in the reader, never null
    1855     * @throws IllegalArgumentException                     if the input is null
    1856     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
    1857     *                                                      .UnsupportedEncodingException} in version 2.2 if the
    1858     *                                                      encoding is not supported.
    1859     * @since 1.2
    1860     */
    1861    public static LineIterator lineIterator(final InputStream input, final String charsetName) {
    1862        return lineIterator(input, Charsets.toCharset(charsetName));
    1863    }
    1864
    1865    /**
    1866     * Returns an Iterator for the lines in a {@link Reader}.
    1867     * <p>
    1868     * {@link LineIterator} holds a reference to the open
    1869     * {@link Reader} specified here. When you have finished with the
    1870     * iterator you should close the reader to free internal resources.
    1871     * This can be done by using a try-with-resources block, closing the reader directly, or by calling
    1872     * {@link LineIterator#close()}.
    1873     * </p>
    1874     * <p>
    1875     * The recommended usage pattern is:
    1876     * </p>
    1877     * <pre>
    1878     * try {
    1879     *   LineIterator it = IOUtils.lineIterator(reader);
    1880     *   while (it.hasNext()) {
    1881     *     String line = it.nextLine();
    1882     *     /// do something with line
    1883     *   }
    1884     * } finally {
    1885     *   IOUtils.closeQuietly(reader);
    1886     * }
    1887     * </pre>
    1888     *
    1889     * @param reader the {@link Reader} to read, not null
    1890     * @return an Iterator of the lines in the reader, never null
    1891     * @throws NullPointerException if the reader is null
    1892     * @since 1.2
    1893     */
    1894    public static LineIterator lineIterator(final Reader reader) {
    1895        return new LineIterator(reader);
    1896    }
    1897
    1898    /**
    1899     * Reads bytes from an input stream.
    1900     * This implementation guarantees that it will read as many bytes
    1901     * as possible before giving up; this may not always be the case for
    1902     * subclasses of {@link InputStream}.
    1903     *
    1904     * @param input where to read input from
    1905     * @param buffer destination
    1906     * @return actual length read; may be less than requested if EOF was reached
    1907     * @throws IOException if a read error occurs
    1908     * @since 2.2
    1909     */
    1910    public static int read(final InputStream input, final byte[] buffer) throws IOException {
    1911        return read(input, buffer, 0, buffer.length);
    1912    }
    1913
    1914    /**
    1915     * Reads bytes from an input stream.
    1916     * This implementation guarantees that it will read as many bytes
    1917     * as possible before giving up; this may not always be the case for
    1918     * subclasses of {@link InputStream}.
    1919     *
    1920     * @param input where to read input
    1921     * @param buffer destination
    1922     * @param offset initial offset into buffer
    1923     * @param length length to read, must be &gt;= 0
    1924     * @return actual length read; may be less than requested if EOF was reached
    1925     * @throws IllegalArgumentException if length is negative
    1926     * @throws IOException              if a read error occurs
    1927     * @since 2.2
    1928     */
    1929    public static int read(final InputStream input, final byte[] buffer, final int offset, final int length)
    1930            throws IOException {
    1931        if (length == 0) {
    1932            return 0;
    1933        }
    1934        return read(input::read, buffer, offset, length);
    1935    }
    1936
    1937    /**
    1938     * 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
    1939     * for subclasses of {@link InputStream}.
    1940     *
    1941     * @param input  How to read input
    1942     * @param buffer destination
    1943     * @param offset initial offset into buffer
    1944     * @param length length to read, must be &gt;= 0
    1945     * @return actual length read; may be less than requested if EOF was reached
    1946     * @throws IllegalArgumentException if length is negative
    1947     * @throws IOException              if a read error occurs
    1948     * @since 2.2
    1949     */
    1950    static int read(final IOTriFunction<byte[], Integer, Integer, Integer> input, final byte[] buffer, final int offset, final int length)
    1951            throws IOException {
    1952        if (length < 0) {
    1953            throw new IllegalArgumentException("Length must not be negative: " + length);
    1954        }
    1955        int remaining = length;
    1956        while (remaining > 0) {
    1957            final int location = length - remaining;
    1958            final int count = input.apply(buffer, offset + location, remaining);
    1959            if (EOF == count) {
    1960                break;
    1961            }
    1962            remaining -= count;
    1963        }
    1964        return length - remaining;
    1965    }
    1966
    1967    /**
    1968     * Reads bytes from a ReadableByteChannel.
    1969     * <p>
    1970     * This implementation guarantees that it will read as many bytes
    1971     * as possible before giving up; this may not always be the case for
    1972     * subclasses of {@link ReadableByteChannel}.
    1973     * </p>
    1974     *
    1975     * @param input the byte channel to read
    1976     * @param buffer byte buffer destination
    1977     * @return the actual length read; may be less than requested if EOF was reached
    1978     * @throws IOException if a read error occurs
    1979     * @since 2.5
    1980     */
    1981    public static int read(final ReadableByteChannel input, final ByteBuffer buffer) throws IOException {
    1982        final int length = buffer.remaining();
    1983        while (buffer.remaining() > 0) {
    1984            final int count = input.read(buffer);
    1985            if (EOF == count) { // EOF
    1986                break;
    1987            }
    1988        }
    1989        return length - buffer.remaining();
    1990    }
    1991
    1992    /**
    1993     * Reads characters from an input character stream.
    1994     * This implementation guarantees that it will read as many characters
    1995     * as possible before giving up; this may not always be the case for
    1996     * subclasses of {@link Reader}.
    1997     *
    1998     * @param reader where to read input from
    1999     * @param buffer destination
    2000     * @return actual length read; may be less than requested if EOF was reached
    2001     * @throws IOException if a read error occurs
    2002     * @since 2.2
    2003     */
    2004    public static int read(final Reader reader, final char[] buffer) throws IOException {
    2005        return read(reader, buffer, 0, buffer.length);
    2006    }
    2007
    2008    /**
    2009     * Reads characters from an input character stream.
    2010     * This implementation guarantees that it will read as many characters
    2011     * as possible before giving up; this may not always be the case for
    2012     * subclasses of {@link Reader}.
    2013     *
    2014     * @param reader where to read input from
    2015     * @param buffer destination
    2016     * @param offset initial offset into buffer
    2017     * @param length length to read, must be &gt;= 0
    2018     * @return actual length read; may be less than requested if EOF was reached
    2019     * @throws IllegalArgumentException if length is negative
    2020     * @throws IOException              if a read error occurs
    2021     * @since 2.2
    2022     */
    2023    public static int read(final Reader reader, final char[] buffer, final int offset, final int length)
    2024            throws IOException {
    2025        if (length < 0) {
    2026            throw new IllegalArgumentException("Length must not be negative: " + length);
    2027        }
    2028        int remaining = length;
    2029        while (remaining > 0) {
    2030            final int location = length - remaining;
    2031            final int count = reader.read(buffer, offset + location, remaining);
    2032            if (EOF == count) { // EOF
    2033                break;
    2034            }
    2035            remaining -= count;
    2036        }
    2037        return length - remaining;
    2038    }
    2039
    2040    /**
    2041     * Reads the requested number of bytes or fail if there are not enough left.
    2042     * <p>
    2043     * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may
    2044     * not read as many bytes as requested (most likely because of reaching EOF).
    2045     * </p>
    2046     *
    2047     * @param input where to read input from
    2048     * @param buffer destination
    2049     *
    2050     * @throws IOException              if there is a problem reading the file
    2051     * @throws IllegalArgumentException if length is negative
    2052     * @throws EOFException             if the number of bytes read was incorrect
    2053     * @since 2.2
    2054     */
    2055    public static void readFully(final InputStream input, final byte[] buffer) throws IOException {
    2056        readFully(input, buffer, 0, buffer.length);
    2057    }
    2058
    2059    /**
    2060     * Reads the requested number of bytes or fail if there are not enough left.
    2061     * <p>
    2062     * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may
    2063     * not read as many bytes as requested (most likely because of reaching EOF).
    2064     * </p>
    2065     *
    2066     * @param input where to read input from
    2067     * @param buffer destination
    2068     * @param offset initial offset into buffer
    2069     * @param length length to read, must be &gt;= 0
    2070     *
    2071     * @throws IOException              if there is a problem reading the file
    2072     * @throws IllegalArgumentException if length is negative
    2073     * @throws EOFException             if the number of bytes read was incorrect
    2074     * @since 2.2
    2075     */
    2076    public static void readFully(final InputStream input, final byte[] buffer, final int offset, final int length)
    2077            throws IOException {
    2078        final int actual = read(input, buffer, offset, length);
    2079        if (actual != length) {
    2080            throw new EOFException("Length to read: " + length + " actual: " + actual);
    2081        }
    2082    }
    2083
    2084    /**
    2085     * Reads the requested number of bytes or fail if there are not enough left.
    2086     * <p>
    2087     * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may
    2088     * not read as many bytes as requested (most likely because of reaching EOF).
    2089     * </p>
    2090     *
    2091     * @param input where to read input from
    2092     * @param length length to read, must be &gt;= 0
    2093     * @return the bytes read from input
    2094     * @throws IOException              if there is a problem reading the file
    2095     * @throws IllegalArgumentException if length is negative
    2096     * @throws EOFException             if the number of bytes read was incorrect
    2097     * @since 2.5
    2098     */
    2099    public static byte[] readFully(final InputStream input, final int length) throws IOException {
    2100        final byte[] buffer = byteArray(length);
    2101        readFully(input, buffer, 0, buffer.length);
    2102        return buffer;
    2103    }
    2104
    2105    /**
    2106     * Reads the requested number of bytes or fail if there are not enough left.
    2107     * <p>
    2108     * This allows for the possibility that {@link ReadableByteChannel#read(ByteBuffer)} may
    2109     * not read as many bytes as requested (most likely because of reaching EOF).
    2110     * </p>
    2111     *
    2112     * @param input the byte channel to read
    2113     * @param buffer byte buffer destination
    2114     * @throws IOException  if there is a problem reading the file
    2115     * @throws EOFException if the number of bytes read was incorrect
    2116     * @since 2.5
    2117     */
    2118    public static void readFully(final ReadableByteChannel input, final ByteBuffer buffer) throws IOException {
    2119        final int expected = buffer.remaining();
    2120        final int actual = read(input, buffer);
    2121        if (actual != expected) {
    2122            throw new EOFException("Length to read: " + expected + " actual: " + actual);
    2123        }
    2124    }
    2125
    2126    /**
    2127     * Reads the requested number of characters or fail if there are not enough left.
    2128     * <p>
    2129     * This allows for the possibility that {@link Reader#read(char[], int, int)} may
    2130     * not read as many characters as requested (most likely because of reaching EOF).
    2131     * </p>
    2132     *
    2133     * @param reader where to read input from
    2134     * @param buffer destination
    2135     * @throws IOException              if there is a problem reading the file
    2136     * @throws IllegalArgumentException if length is negative
    2137     * @throws EOFException             if the number of characters read was incorrect
    2138     * @since 2.2
    2139     */
    2140    public static void readFully(final Reader reader, final char[] buffer) throws IOException {
    2141        readFully(reader, buffer, 0, buffer.length);
    2142    }
    2143
    2144    /**
    2145     * Reads the requested number of characters or fail if there are not enough left.
    2146     * <p>
    2147     * This allows for the possibility that {@link Reader#read(char[], int, int)} may
    2148     * not read as many characters as requested (most likely because of reaching EOF).
    2149     * </p>
    2150     *
    2151     * @param reader where to read input from
    2152     * @param buffer destination
    2153     * @param offset initial offset into buffer
    2154     * @param length length to read, must be &gt;= 0
    2155     * @throws IOException              if there is a problem reading the file
    2156     * @throws IllegalArgumentException if length is negative
    2157     * @throws EOFException             if the number of characters read was incorrect
    2158     * @since 2.2
    2159     */
    2160    public static void readFully(final Reader reader, final char[] buffer, final int offset, final int length)
    2161            throws IOException {
    2162        final int actual = read(reader, buffer, offset, length);
    2163        if (actual != length) {
    2164            throw new EOFException("Length to read: " + length + " actual: " + actual);
    2165        }
    2166    }
    2167
    2168    /**
    2169     * Gets the contents of an {@link InputStream} as a list of Strings,
    2170     * one entry per line, using the default character encoding of the platform.
    2171     * <p>
    2172     * This method buffers the input internally, so there is no need to use a
    2173     * {@link BufferedInputStream}.
    2174     * </p>
    2175     *
    2176     * @param input the {@link InputStream} to read, not null
    2177     * @return the list of Strings, never null
    2178     * @throws NullPointerException if the input is null
    2179     * @throws UncheckedIOException if an I/O error occurs
    2180     * @since 1.1
    2181     * @deprecated 2.5 use {@link #readLines(InputStream, Charset)} instead
    2182     */
    2183    @Deprecated
    2184    public static List<String> readLines(final InputStream input) throws UncheckedIOException {
    2185        return readLines(input, Charset.defaultCharset());
    2186    }
    2187
    2188    /**
    2189     * Gets the contents of an {@link InputStream} as a list of Strings,
    2190     * one entry per line, using the specified character encoding.
    2191     * <p>
    2192     * This method buffers the input internally, so there is no need to use a
    2193     * {@link BufferedInputStream}.
    2194     * </p>
    2195     *
    2196     * @param input the {@link InputStream} to read, not null
    2197     * @param charset the charset to use, null means platform default
    2198     * @return the list of Strings, never null
    2199     * @throws NullPointerException if the input is null
    2200     * @throws UncheckedIOException if an I/O error occurs
    2201     * @since 2.3
    2202     */
    2203    public static List<String> readLines(final InputStream input, final Charset charset) throws UncheckedIOException {
    2204        return readLines(new InputStreamReader(input, Charsets.toCharset(charset)));
    2205    }
    2206
    2207    /**
    2208     * Gets the contents of an {@link InputStream} as a list of Strings,
    2209     * one entry per line, using the specified character encoding.
    2210     * <p>
    2211     * Character encoding names can be found at
    2212     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    2213     * </p>
    2214     * <p>
    2215     * This method buffers the input internally, so there is no need to use a
    2216     * {@link BufferedInputStream}.
    2217     * </p>
    2218     *
    2219     * @param input the {@link InputStream} to read, not null
    2220     * @param charsetName the name of the requested charset, null means platform default
    2221     * @return the list of Strings, never null
    2222     * @throws NullPointerException                         if the input is null
    2223     * @throws UncheckedIOException                         if an I/O error occurs
    2224     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
    2225     *                                                      .UnsupportedEncodingException} in version 2.2 if the
    2226     *                                                      encoding is not supported.
    2227     * @since 1.1
    2228     */
    2229    public static List<String> readLines(final InputStream input, final String charsetName) throws UncheckedIOException {
    2230        return readLines(input, Charsets.toCharset(charsetName));
    2231    }
    2232
    2233    /**
    2234     * Gets the contents of a {@link Reader} as a list of Strings,
    2235     * one entry per line.
    2236     * <p>
    2237     * This method buffers the input internally, so there is no need to use a
    2238     * {@link BufferedReader}.
    2239     * </p>
    2240     *
    2241     * @param reader the {@link Reader} to read, not null
    2242     * @return the list of Strings, never null
    2243     * @throws NullPointerException if the input is null
    2244     * @throws UncheckedIOException if an I/O error occurs
    2245     * @since 1.1
    2246     */
    2247    @SuppressWarnings("resource") // reader wraps input and is the responsibility of the caller.
    2248    public static List<String> readLines(final Reader reader) throws UncheckedIOException {
    2249        return toBufferedReader(reader).lines().collect(Collectors.toList());
    2250    }
    2251
    2252    /**
    2253     * Gets the contents of a resource as a byte array.
    2254     * <p>
    2255     * Delegates to {@link #resourceToByteArray(String, ClassLoader) resourceToByteArray(String, null)}.
    2256     * </p>
    2257     *
    2258     * @param name The resource name.
    2259     * @return the requested byte array
    2260     * @throws IOException if an I/O error occurs or the resource is not found.
    2261     * @see #resourceToByteArray(String, ClassLoader)
    2262     * @since 2.6
    2263     */
    2264    public static byte[] resourceToByteArray(final String name) throws IOException {
    2265        return resourceToByteArray(name, null);
    2266    }
    2267
    2268    /**
    2269     * Gets the contents of a resource as a byte array.
    2270     * <p>
    2271     * Delegates to {@link #resourceToURL(String, ClassLoader)}.
    2272     * </p>
    2273     *
    2274     * @param name The resource name.
    2275     * @param classLoader the class loader that the resolution of the resource is delegated to
    2276     * @return the requested byte array
    2277     * @throws IOException if an I/O error occurs or the resource is not found.
    2278     * @see #resourceToURL(String, ClassLoader)
    2279     * @since 2.6
    2280     */
    2281    public static byte[] resourceToByteArray(final String name, final ClassLoader classLoader) throws IOException {
    2282        return toByteArray(resourceToURL(name, classLoader));
    2283    }
    2284
    2285    /**
    2286     * Gets the contents of a resource as a String using the specified character encoding.
    2287     * <p>
    2288     * Delegates to {@link #resourceToString(String, Charset, ClassLoader) resourceToString(String, Charset, null)}.
    2289     * </p>
    2290     *
    2291     * @param name The resource name.
    2292     * @param charset the charset to use, null means platform default
    2293     * @return the requested String
    2294     * @throws IOException if an I/O error occurs or the resource is not found.
    2295     * @see #resourceToString(String, Charset, ClassLoader)
    2296     * @since 2.6
    2297     */
    2298    public static String resourceToString(final String name, final Charset charset) throws IOException {
    2299        return resourceToString(name, charset, null);
    2300    }
    2301
    2302    /**
    2303     * Gets the contents of a resource as a String using the specified character encoding.
    2304     * <p>
    2305     * Delegates to {@link #resourceToURL(String, ClassLoader)}.
    2306     * </p>
    2307     *
    2308     * @param name The resource name.
    2309     * @param charset the Charset to use, null means platform default
    2310     * @param classLoader the class loader that the resolution of the resource is delegated to
    2311     * @return the requested String
    2312     * @throws IOException if an I/O error occurs.
    2313     * @see #resourceToURL(String, ClassLoader)
    2314     * @since 2.6
    2315     */
    2316    public static String resourceToString(final String name, final Charset charset, final ClassLoader classLoader) throws IOException {
    2317        return toString(resourceToURL(name, classLoader), charset);
    2318    }
    2319
    2320    /**
    2321     * Gets a URL pointing to the given resource.
    2322     * <p>
    2323     * Delegates to {@link #resourceToURL(String, ClassLoader) resourceToURL(String, null)}.
    2324     * </p>
    2325     *
    2326     * @param name The resource name.
    2327     * @return A URL object for reading the resource.
    2328     * @throws IOException if the resource is not found.
    2329     * @since 2.6
    2330     */
    2331    public static URL resourceToURL(final String name) throws IOException {
    2332        return resourceToURL(name, null);
    2333    }
    2334
    2335    /**
    2336     * Gets a URL pointing to the given resource.
    2337     * <p>
    2338     * If the {@code classLoader} is not null, call {@link ClassLoader#getResource(String)}, otherwise call
    2339     * {@link Class#getResource(String) IOUtils.class.getResource(name)}.
    2340     * </p>
    2341     *
    2342     * @param name The resource name.
    2343     * @param classLoader Delegate to this class loader if not null
    2344     * @return A URL object for reading the resource.
    2345     * @throws IOException if the resource is not found.
    2346     * @since 2.6
    2347     */
    2348    public static URL resourceToURL(final String name, final ClassLoader classLoader) throws IOException {
    2349        // What about the thread context class loader?
    2350        // What about the system class loader?
    2351        final URL resource = classLoader == null ? IOUtils.class.getResource(name) : classLoader.getResource(name);
    2352        if (resource == null) {
    2353            throw new IOException("Resource not found: " + name);
    2354        }
    2355        return resource;
    2356    }
    2357
    2358    /**
    2359     * Skips bytes from an input byte stream.
    2360     * This implementation guarantees that it will read as many bytes
    2361     * as possible before giving up; this may not always be the case for
    2362     * skip() implementations in subclasses of {@link InputStream}.
    2363     * <p>
    2364     * Note that the implementation uses {@link InputStream#read(byte[], int, int)} rather
    2365     * than delegating to {@link InputStream#skip(long)}.
    2366     * This means that the method may be considerably less efficient than using the actual skip implementation,
    2367     * this is done to guarantee that the correct number of bytes are skipped.
    2368     * </p>
    2369     *
    2370     * @param input byte stream to skip
    2371     * @param toSkip number of bytes to skip.
    2372     * @return number of bytes actually skipped.
    2373     * @throws IOException              if there is a problem reading the file
    2374     * @throws IllegalArgumentException if toSkip is negative
    2375     * @see InputStream#skip(long)
    2376     * @see <a href="https://issues.apache.org/jira/browse/IO-203">IO-203 - Add skipFully() method for InputStreams</a>
    2377     * @since 2.0
    2378     */
    2379    public static long skip(final InputStream input, final long toSkip) throws IOException {
    2380        return skip(input, toSkip, IOUtils::getScratchByteArrayWriteOnly);
    2381    }
    2382
    2383    /**
    2384     * Skips bytes from an input byte stream.
    2385     * <p>
    2386     * Intended for special cases when customization of the temporary buffer is needed because, for example, a nested input stream has requirements for the
    2387     * bytes read. For example, when using {@link InflaterInputStream}s from multiple threads.
    2388     * </p>
    2389     * <p>
    2390     * 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
    2391     * in subclasses of {@link InputStream}.
    2392     * </p>
    2393     * <p>
    2394     * Note that the implementation uses {@link InputStream#read(byte[], int, int)} rather than delegating to {@link InputStream#skip(long)}. This means that
    2395     * 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
    2396     * skipped.
    2397     * </p>
    2398     *
    2399     * @param input              byte stream to skip
    2400     * @param toSkip             number of bytes to skip.
    2401     * @param skipBufferSupplier Supplies the buffer to use for reading.
    2402     * @return number of bytes actually skipped.
    2403     * @throws IOException              if there is a problem reading the file
    2404     * @throws IllegalArgumentException if toSkip is negative
    2405     * @see InputStream#skip(long)
    2406     * @see <a href="https://issues.apache.org/jira/browse/IO-203">IO-203 - Add skipFully() method for InputStreams</a>
    2407     * @since 2.14.0
    2408     */
    2409    public static long skip(final InputStream input, final long toSkip, final Supplier<byte[]> skipBufferSupplier) throws IOException {
    2410        if (toSkip < 0) {
    2411            throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip);
    2412        }
    2413        //
    2414        // No need to synchronize access to SCRATCH_BYTE_BUFFER_WO: We don't care if the buffer is written multiple
    2415        // times or in parallel since the data is ignored. We reuse the same buffer, if the buffer size were variable or read-write,
    2416        // we would need to synch or use a thread local to ensure some other thread safety.
    2417        //
    2418        long remain = toSkip;
    2419        while (remain > 0) {
    2420            final byte[] skipBuffer = skipBufferSupplier.get();
    2421            // See https://issues.apache.org/jira/browse/IO-203 for why we use read() rather than delegating to skip()
    2422            final long n = input.read(skipBuffer, 0, (int) Math.min(remain, skipBuffer.length));
    2423            if (n < 0) { // EOF
    2424                break;
    2425            }
    2426            remain -= n;
    2427        }
    2428        return toSkip - remain;
    2429    }
    2430
    2431    /**
    2432     * Skips bytes from a ReadableByteChannel.
    2433     * This implementation guarantees that it will read as many bytes
    2434     * as possible before giving up.
    2435     *
    2436     * @param input ReadableByteChannel to skip
    2437     * @param toSkip number of bytes to skip.
    2438     * @return number of bytes actually skipped.
    2439     * @throws IOException              if there is a problem reading the ReadableByteChannel
    2440     * @throws IllegalArgumentException if toSkip is negative
    2441     * @since 2.5
    2442     */
    2443    public static long skip(final ReadableByteChannel input, final long toSkip) throws IOException {
    2444        if (toSkip < 0) {
    2445            throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip);
    2446        }
    2447        final ByteBuffer skipByteBuffer = ByteBuffer.allocate((int) Math.min(toSkip, DEFAULT_BUFFER_SIZE));
    2448        long remain = toSkip;
    2449        while (remain > 0) {
    2450            skipByteBuffer.position(0);
    2451            skipByteBuffer.limit((int) Math.min(remain, DEFAULT_BUFFER_SIZE));
    2452            final int n = input.read(skipByteBuffer);
    2453            if (n == EOF) {
    2454                break;
    2455            }
    2456            remain -= n;
    2457        }
    2458        return toSkip - remain;
    2459    }
    2460
    2461    /**
    2462     * Skips characters from an input character stream.
    2463     * This implementation guarantees that it will read as many characters
    2464     * as possible before giving up; this may not always be the case for
    2465     * skip() implementations in subclasses of {@link Reader}.
    2466     * <p>
    2467     * Note that the implementation uses {@link Reader#read(char[], int, int)} rather
    2468     * than delegating to {@link Reader#skip(long)}.
    2469     * This means that the method may be considerably less efficient than using the actual skip implementation,
    2470     * this is done to guarantee that the correct number of characters are skipped.
    2471     * </p>
    2472     *
    2473     * @param reader character stream to skip
    2474     * @param toSkip number of characters to skip.
    2475     * @return number of characters actually skipped.
    2476     * @throws IOException              if there is a problem reading the file
    2477     * @throws IllegalArgumentException if toSkip is negative
    2478     * @see Reader#skip(long)
    2479     * @see <a href="https://issues.apache.org/jira/browse/IO-203">IO-203 - Add skipFully() method for InputStreams</a>
    2480     * @since 2.0
    2481     */
    2482    public static long skip(final Reader reader, final long toSkip) throws IOException {
    2483        if (toSkip < 0) {
    2484            throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip);
    2485        }
    2486        long remain = toSkip;
    2487        while (remain > 0) {
    2488            // See https://issues.apache.org/jira/browse/IO-203 for why we use read() rather than delegating to skip()
    2489            final char[] charArray = getScratchCharArrayWriteOnly();
    2490            final long n = reader.read(charArray, 0, (int) Math.min(remain, charArray.length));
    2491            if (n < 0) { // EOF
    2492                break;
    2493            }
    2494            remain -= n;
    2495        }
    2496        return toSkip - remain;
    2497    }
    2498
    2499    /**
    2500     * Skips the requested number of bytes or fail if there are not enough left.
    2501     * <p>
    2502     * This allows for the possibility that {@link InputStream#skip(long)} may
    2503     * not skip as many bytes as requested (most likely because of reaching EOF).
    2504     * </p>
    2505     * <p>
    2506     * Note that the implementation uses {@link #skip(InputStream, long)}.
    2507     * This means that the method may be considerably less efficient than using the actual skip implementation,
    2508     * this is done to guarantee that the correct number of characters are skipped.
    2509     * </p>
    2510     *
    2511     * @param input stream to skip
    2512     * @param toSkip the number of bytes to skip
    2513     * @throws IOException              if there is a problem reading the file
    2514     * @throws IllegalArgumentException if toSkip is negative
    2515     * @throws EOFException             if the number of bytes skipped was incorrect
    2516     * @see InputStream#skip(long)
    2517     * @since 2.0
    2518     */
    2519    public static void skipFully(final InputStream input, final long toSkip) throws IOException {
    2520        final long skipped = skip(input, toSkip, IOUtils::getScratchByteArrayWriteOnly);
    2521        if (skipped != toSkip) {
    2522            throw new EOFException("Bytes to skip: " + toSkip + " actual: " + skipped);
    2523        }
    2524    }
    2525
    2526    /**
    2527     * Skips the requested number of bytes or fail if there are not enough left.
    2528     * <p>
    2529     * Intended for special cases when customization of the temporary buffer is needed because, for example, a nested input stream has requirements for the
    2530     * bytes read. For example, when using {@link InflaterInputStream}s from multiple threads.
    2531     * </p>
    2532     * <p>
    2533     * This allows for the possibility that {@link InputStream#skip(long)} may not skip as many bytes as requested (most likely because of reaching EOF).
    2534     * </p>
    2535     * <p>
    2536     * Note that the implementation uses {@link #skip(InputStream, long)}. This means that the method may be considerably less efficient than using the actual
    2537     * skip implementation, this is done to guarantee that the correct number of characters are skipped.
    2538     * </p>
    2539     *
    2540     * @param input              stream to skip
    2541     * @param toSkip             the number of bytes to skip
    2542     * @param skipBufferSupplier Supplies the buffer to use for reading.
    2543     * @throws IOException              if there is a problem reading the file
    2544     * @throws IllegalArgumentException if toSkip is negative
    2545     * @throws EOFException             if the number of bytes skipped was incorrect
    2546     * @see InputStream#skip(long)
    2547     * @since 2.14.0
    2548     */
    2549    public static void skipFully(final InputStream input, final long toSkip, final Supplier<byte[]> skipBufferSupplier) throws IOException {
    2550        if (toSkip < 0) {
    2551            throw new IllegalArgumentException("Bytes to skip must not be negative: " + toSkip);
    2552        }
    2553        final long skipped = skip(input, toSkip, skipBufferSupplier);
    2554        if (skipped != toSkip) {
    2555            throw new EOFException("Bytes to skip: " + toSkip + " actual: " + skipped);
    2556        }
    2557    }
    2558
    2559    /**
    2560     * Skips the requested number of bytes or fail if there are not enough left.
    2561     *
    2562     * @param input ReadableByteChannel to skip
    2563     * @param toSkip the number of bytes to skip
    2564     * @throws IOException              if there is a problem reading the ReadableByteChannel
    2565     * @throws IllegalArgumentException if toSkip is negative
    2566     * @throws EOFException             if the number of bytes skipped was incorrect
    2567     * @since 2.5
    2568     */
    2569    public static void skipFully(final ReadableByteChannel input, final long toSkip) throws IOException {
    2570        if (toSkip < 0) {
    2571            throw new IllegalArgumentException("Bytes to skip must not be negative: " + toSkip);
    2572        }
    2573        final long skipped = skip(input, toSkip);
    2574        if (skipped != toSkip) {
    2575            throw new EOFException("Bytes to skip: " + toSkip + " actual: " + skipped);
    2576        }
    2577    }
    2578
    2579    /**
    2580     * Skips the requested number of characters or fail if there are not enough left.
    2581     * <p>
    2582     * This allows for the possibility that {@link Reader#skip(long)} may
    2583     * not skip as many characters as requested (most likely because of reaching EOF).
    2584     * </p>
    2585     * <p>
    2586     * Note that the implementation uses {@link #skip(Reader, long)}.
    2587     * This means that the method may be considerably less efficient than using the actual skip implementation,
    2588     * this is done to guarantee that the correct number of characters are skipped.
    2589     * </p>
    2590     *
    2591     * @param reader stream to skip
    2592     * @param toSkip the number of characters to skip
    2593     * @throws IOException              if there is a problem reading the file
    2594     * @throws IllegalArgumentException if toSkip is negative
    2595     * @throws EOFException             if the number of characters skipped was incorrect
    2596     * @see Reader#skip(long)
    2597     * @since 2.0
    2598     */
    2599    public static void skipFully(final Reader reader, final long toSkip) throws IOException {
    2600        final long skipped = skip(reader, toSkip);
    2601        if (skipped != toSkip) {
    2602            throw new EOFException("Chars to skip: " + toSkip + " actual: " + skipped);
    2603        }
    2604    }
    2605
    2606    /**
    2607     * Fetches entire contents of an {@link InputStream} and represent
    2608     * same data as result InputStream.
    2609     * <p>
    2610     * This method is useful where,
    2611     * </p>
    2612     * <ul>
    2613     * <li>Source InputStream is slow.</li>
    2614     * <li>It has network resources associated, so we cannot keep it open for
    2615     * long time.</li>
    2616     * <li>It has network timeout associated.</li>
    2617     * </ul>
    2618     * <p>
    2619     * It can be used in favor of {@link #toByteArray(InputStream)}, since it
    2620     * avoids unnecessary allocation and copy of byte[].<br>
    2621     * This method buffers the input internally, so there is no need to use a
    2622     * {@link BufferedInputStream}.
    2623     * </p>
    2624     *
    2625     * @param input Stream to be fully buffered.
    2626     * @return A fully buffered stream.
    2627     * @throws IOException if an I/O error occurs.
    2628     * @since 2.0
    2629     */
    2630    public static InputStream toBufferedInputStream(final InputStream input) throws IOException {
    2631        return ByteArrayOutputStream.toBufferedInputStream(input);
    2632    }
    2633
    2634    /**
    2635     * Fetches entire contents of an {@link InputStream} and represent
    2636     * same data as result InputStream.
    2637     * <p>
    2638     * This method is useful where,
    2639     * </p>
    2640     * <ul>
    2641     * <li>Source InputStream is slow.</li>
    2642     * <li>It has network resources associated, so we cannot keep it open for
    2643     * long time.</li>
    2644     * <li>It has network timeout associated.</li>
    2645     * </ul>
    2646     * <p>
    2647     * It can be used in favor of {@link #toByteArray(InputStream)}, since it
    2648     * avoids unnecessary allocation and copy of byte[].<br>
    2649     * This method buffers the input internally, so there is no need to use a
    2650     * {@link BufferedInputStream}.
    2651     * </p>
    2652     *
    2653     * @param input Stream to be fully buffered.
    2654     * @param size the initial buffer size
    2655     * @return A fully buffered stream.
    2656     * @throws IOException if an I/O error occurs.
    2657     * @since 2.5
    2658     */
    2659    public static InputStream toBufferedInputStream(final InputStream input, final int size) throws IOException {
    2660        return ByteArrayOutputStream.toBufferedInputStream(input, size);
    2661    }
    2662
    2663    /**
    2664     * Returns the given reader if it is a {@link BufferedReader}, otherwise creates a BufferedReader from the given
    2665     * reader.
    2666     *
    2667     * @param reader the reader to wrap or return (not null)
    2668     * @return the given reader or a new {@link BufferedReader} for the given reader
    2669     * @throws NullPointerException if the input parameter is null
    2670     * @see #buffer(Reader)
    2671     * @since 2.2
    2672     */
    2673    public static BufferedReader toBufferedReader(final Reader reader) {
    2674        return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader);
    2675    }
    2676
    2677    /**
    2678     * Returns the given reader if it is a {@link BufferedReader}, otherwise creates a BufferedReader from the given
    2679     * reader.
    2680     *
    2681     * @param reader the reader to wrap or return (not null)
    2682     * @param size the buffer size, if a new BufferedReader is created.
    2683     * @return the given reader or a new {@link BufferedReader} for the given reader
    2684     * @throws NullPointerException if the input parameter is null
    2685     * @see #buffer(Reader)
    2686     * @since 2.5
    2687     */
    2688    public static BufferedReader toBufferedReader(final Reader reader, final int size) {
    2689        return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader, size);
    2690    }
    2691
    2692    /**
    2693     * Gets the contents of an {@link InputStream} as a {@code byte[]}.
    2694     * <p>
    2695     * This method buffers the input internally, so there is no need to use a
    2696     * {@link BufferedInputStream}.
    2697     * </p>
    2698     *
    2699     * @param inputStream the {@link InputStream} to read.
    2700     * @return the requested byte array.
    2701     * @throws NullPointerException if the InputStream is {@code null}.
    2702     * @throws IOException if an I/O error occurs or reading more than {@link Integer#MAX_VALUE} occurs.
    2703     */
    2704    public static byte[] toByteArray(final InputStream inputStream) throws IOException {
    2705        // We use a ThresholdingOutputStream to avoid reading AND writing more than Integer.MAX_VALUE.
    2706        try (UnsynchronizedByteArrayOutputStream ubaOutput = UnsynchronizedByteArrayOutputStream.builder().get();
    2707            ThresholdingOutputStream thresholdOutput = new ThresholdingOutputStream(Integer.MAX_VALUE, os -> {
    2708                throw new IllegalArgumentException(String.format("Cannot read more than %,d into a byte array", Integer.MAX_VALUE));
    2709            }, os -> ubaOutput)) {
    2710            copy(inputStream, thresholdOutput);
    2711            return ubaOutput.toByteArray();
    2712        }
    2713    }
    2714
    2715    /**
    2716     * Gets the contents of an {@link InputStream} as a {@code byte[]}. Use this method instead of
    2717     * {@link #toByteArray(InputStream)} when {@link InputStream} size is known.
    2718     *
    2719     * @param input the {@link InputStream} to read.
    2720     * @param size the size of {@link InputStream} to read, where 0 &lt; {@code size} &lt;= length of input stream.
    2721     * @return byte [] of length {@code size}.
    2722     * @throws IOException if an I/O error occurs or {@link InputStream} length is smaller than parameter {@code size}.
    2723     * @throws IllegalArgumentException if {@code size} is less than zero.
    2724     * @since 2.1
    2725     */
    2726    public static byte[] toByteArray(final InputStream input, final int size) throws IOException {
    2727        if (size == 0) {
    2728            return EMPTY_BYTE_ARRAY;
    2729        }
    2730        return toByteArray(Objects.requireNonNull(input, "input")::read, size);
    2731    }
    2732
    2733    /**
    2734     * Gets contents of an {@link InputStream} as a {@code byte[]}.
    2735     * Use this method instead of {@link #toByteArray(InputStream)}
    2736     * when {@link InputStream} size is known.
    2737     * <b>NOTE:</b> the method checks that the length can safely be cast to an int without truncation
    2738     * before using {@link IOUtils#toByteArray(InputStream, int)} to read into the byte array.
    2739     * (Arrays can have no more than Integer.MAX_VALUE entries anyway)
    2740     *
    2741     * @param input the {@link InputStream} to read
    2742     * @param size the size of {@link InputStream} to read, where 0 &lt; {@code size} &lt;= min(Integer.MAX_VALUE, length of input stream).
    2743     * @return byte [] the requested byte array, of length {@code size}
    2744     * @throws IOException              if an I/O error occurs or {@link InputStream} length is less than {@code size}
    2745     * @throws IllegalArgumentException if size is less than zero or size is greater than Integer.MAX_VALUE
    2746     * @see IOUtils#toByteArray(InputStream, int)
    2747     * @since 2.1
    2748     */
    2749    public static byte[] toByteArray(final InputStream input, final long size) throws IOException {
    2750        if (size > Integer.MAX_VALUE) {
    2751            throw new IllegalArgumentException("Size cannot be greater than Integer max value: " + size);
    2752        }
    2753        return toByteArray(input, (int) size);
    2754    }
    2755
    2756    /**
    2757     * Gets the contents of an input as a {@code byte[]}.
    2758     *
    2759     * @param input the input to read.
    2760     * @param size the size of the input to read, where 0 &lt; {@code size} &lt;= length of input.
    2761     * @return byte [] of length {@code size}.
    2762     * @throws IOException if an I/O error occurs or input length is smaller than parameter {@code size}.
    2763     * @throws IllegalArgumentException if {@code size} is less than zero.
    2764     */
    2765    static byte[] toByteArray(final IOTriFunction<byte[], Integer, Integer, Integer> input, final int size) throws IOException {
    2766
    2767        if (size < 0) {
    2768            throw new IllegalArgumentException("Size must be equal or greater than zero: " + size);
    2769        }
    2770
    2771        if (size == 0) {
    2772            return EMPTY_BYTE_ARRAY;
    2773        }
    2774
    2775        final byte[] data = byteArray(size);
    2776        int offset = 0;
    2777        int read;
    2778
    2779        while (offset < size && (read = input.apply(data, offset, size - offset)) != EOF) {
    2780            offset += read;
    2781        }
    2782
    2783        if (offset != size) {
    2784            throw new IOException("Unexpected read size, current: " + offset + ", expected: " + size);
    2785        }
    2786
    2787        return data;
    2788    }
    2789
    2790    /**
    2791     * Gets the contents of a {@link Reader} as a {@code byte[]}
    2792     * using the default character encoding of the platform.
    2793     * <p>
    2794     * This method buffers the input internally, so there is no need to use a
    2795     * {@link BufferedReader}.
    2796     * </p>
    2797     *
    2798     * @param reader the {@link Reader} to read
    2799     * @return the requested byte array
    2800     * @throws NullPointerException if the input is null
    2801     * @throws IOException          if an I/O error occurs
    2802     * @deprecated 2.5 use {@link #toByteArray(Reader, Charset)} instead
    2803     */
    2804    @Deprecated
    2805    public static byte[] toByteArray(final Reader reader) throws IOException {
    2806        return toByteArray(reader, Charset.defaultCharset());
    2807    }
    2808
    2809    /**
    2810     * Gets the contents of a {@link Reader} as a {@code byte[]}
    2811     * using the specified character encoding.
    2812     * <p>
    2813     * This method buffers the input internally, so there is no need to use a
    2814     * {@link BufferedReader}.
    2815     * </p>
    2816     *
    2817     * @param reader the {@link Reader} to read
    2818     * @param charset the charset to use, null means platform default
    2819     * @return the requested byte array
    2820     * @throws NullPointerException if the input is null
    2821     * @throws IOException          if an I/O error occurs
    2822     * @since 2.3
    2823     */
    2824    public static byte[] toByteArray(final Reader reader, final Charset charset) throws IOException {
    2825        try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
    2826            copy(reader, output, charset);
    2827            return output.toByteArray();
    2828        }
    2829    }
    2830
    2831    /**
    2832     * Gets the contents of a {@link Reader} as a {@code byte[]}
    2833     * using the specified character encoding.
    2834     * <p>
    2835     * Character encoding names can be found at
    2836     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    2837     * </p>
    2838     * <p>
    2839     * This method buffers the input internally, so there is no need to use a
    2840     * {@link BufferedReader}.
    2841     * </p>
    2842     *
    2843     * @param reader the {@link Reader} to read
    2844     * @param charsetName the name of the requested charset, null means platform default
    2845     * @return the requested byte array
    2846     * @throws NullPointerException                         if the input is null
    2847     * @throws IOException                                  if an I/O error occurs
    2848     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
    2849     *                                                      .UnsupportedEncodingException} in version 2.2 if the
    2850     *                                                      encoding is not supported.
    2851     * @since 1.1
    2852     */
    2853    public static byte[] toByteArray(final Reader reader, final String charsetName) throws IOException {
    2854        return toByteArray(reader, Charsets.toCharset(charsetName));
    2855    }
    2856
    2857    /**
    2858     * Gets the contents of a {@link String} as a {@code byte[]}
    2859     * using the default character encoding of the platform.
    2860     * <p>
    2861     * This is the same as {@link String#getBytes()}.
    2862     * </p>
    2863     *
    2864     * @param input the {@link String} to convert
    2865     * @return the requested byte array
    2866     * @throws NullPointerException if the input is null
    2867     * @deprecated 2.5 Use {@link String#getBytes()} instead
    2868     */
    2869    @Deprecated
    2870    public static byte[] toByteArray(final String input) {
    2871        // make explicit the use of the default charset
    2872        return input.getBytes(Charset.defaultCharset());
    2873    }
    2874
    2875    /**
    2876     * Gets the contents of a {@link URI} as a {@code byte[]}.
    2877     *
    2878     * @param uri the {@link URI} to read
    2879     * @return the requested byte array
    2880     * @throws NullPointerException if the uri is null
    2881     * @throws IOException          if an I/O exception occurs
    2882     * @since 2.4
    2883     */
    2884    public static byte[] toByteArray(final URI uri) throws IOException {
    2885        return toByteArray(uri.toURL());
    2886    }
    2887
    2888    /**
    2889     * Gets the contents of a {@link URL} as a {@code byte[]}.
    2890     *
    2891     * @param url the {@link URL} to read
    2892     * @return the requested byte array
    2893     * @throws NullPointerException if the input is null
    2894     * @throws IOException          if an I/O exception occurs
    2895     * @since 2.4
    2896     */
    2897    public static byte[] toByteArray(final URL url) throws IOException {
    2898        try (CloseableURLConnection urlConnection = CloseableURLConnection.open(url)) {
    2899            return toByteArray(urlConnection);
    2900        }
    2901    }
    2902
    2903    /**
    2904     * Gets the contents of a {@link URLConnection} as a {@code byte[]}.
    2905     *
    2906     * @param urlConnection the {@link URLConnection} to read.
    2907     * @return the requested byte array.
    2908     * @throws NullPointerException if the urlConn is null.
    2909     * @throws IOException if an I/O exception occurs.
    2910     * @since 2.4
    2911     */
    2912    public static byte[] toByteArray(final URLConnection urlConnection) throws IOException {
    2913        try (InputStream inputStream = urlConnection.getInputStream()) {
    2914            return toByteArray(inputStream);
    2915        }
    2916    }
    2917
    2918    /**
    2919     * Gets the contents of an {@link InputStream} as a character array
    2920     * using the default character encoding of the platform.
    2921     * <p>
    2922     * This method buffers the input internally, so there is no need to use a
    2923     * {@link BufferedInputStream}.
    2924     * </p>
    2925     *
    2926     * @param inputStream the {@link InputStream} to read
    2927     * @return the requested character array
    2928     * @throws NullPointerException if the input is null
    2929     * @throws IOException          if an I/O error occurs
    2930     * @since 1.1
    2931     * @deprecated 2.5 use {@link #toCharArray(InputStream, Charset)} instead
    2932     */
    2933    @Deprecated
    2934    public static char[] toCharArray(final InputStream inputStream) throws IOException {
    2935        return toCharArray(inputStream, Charset.defaultCharset());
    2936    }
    2937
    2938    /**
    2939     * Gets the contents of an {@link InputStream} as a character array
    2940     * using the specified character encoding.
    2941     * <p>
    2942     * This method buffers the input internally, so there is no need to use a
    2943     * {@link BufferedInputStream}.
    2944     * </p>
    2945     *
    2946     * @param inputStream the {@link InputStream} to read
    2947     * @param charset the charset to use, null means platform default
    2948     * @return the requested character array
    2949     * @throws NullPointerException if the input is null
    2950     * @throws IOException          if an I/O error occurs
    2951     * @since 2.3
    2952     */
    2953    public static char[] toCharArray(final InputStream inputStream, final Charset charset)
    2954            throws IOException {
    2955        final CharArrayWriter writer = new CharArrayWriter();
    2956        copy(inputStream, writer, charset);
    2957        return writer.toCharArray();
    2958    }
    2959
    2960    /**
    2961     * Gets the contents of an {@link InputStream} as a character array
    2962     * using the specified character encoding.
    2963     * <p>
    2964     * Character encoding names can be found at
    2965     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    2966     * </p>
    2967     * <p>
    2968     * This method buffers the input internally, so there is no need to use a
    2969     * {@link BufferedInputStream}.
    2970     * </p>
    2971     *
    2972     * @param inputStream the {@link InputStream} to read
    2973     * @param charsetName the name of the requested charset, null means platform default
    2974     * @return the requested character array
    2975     * @throws NullPointerException                         if the input is null
    2976     * @throws IOException                                  if an I/O error occurs
    2977     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
    2978     *                                                      .UnsupportedEncodingException} in version 2.2 if the
    2979     *                                                      encoding is not supported.
    2980     * @since 1.1
    2981     */
    2982    public static char[] toCharArray(final InputStream inputStream, final String charsetName) throws IOException {
    2983        return toCharArray(inputStream, Charsets.toCharset(charsetName));
    2984    }
    2985
    2986    /**
    2987     * Gets the contents of a {@link Reader} as a character array.
    2988     * <p>
    2989     * This method buffers the input internally, so there is no need to use a
    2990     * {@link BufferedReader}.
    2991     * </p>
    2992     *
    2993     * @param reader the {@link Reader} to read
    2994     * @return the requested character array
    2995     * @throws NullPointerException if the input is null
    2996     * @throws IOException          if an I/O error occurs
    2997     * @since 1.1
    2998     */
    2999    public static char[] toCharArray(final Reader reader) throws IOException {
    3000        final CharArrayWriter sw = new CharArrayWriter();
    3001        copy(reader, sw);
    3002        return sw.toCharArray();
    3003    }
    3004
    3005    /**
    3006     * Converts the specified CharSequence to an input stream, encoded as bytes
    3007     * using the default character encoding of the platform.
    3008     *
    3009     * @param input the CharSequence to convert
    3010     * @return an input stream
    3011     * @since 2.0
    3012     * @deprecated 2.5 use {@link #toInputStream(CharSequence, Charset)} instead
    3013     */
    3014    @Deprecated
    3015    public static InputStream toInputStream(final CharSequence input) {
    3016        return toInputStream(input, Charset.defaultCharset());
    3017    }
    3018
    3019    /**
    3020     * Converts the specified CharSequence to an input stream, encoded as bytes
    3021     * using the specified character encoding.
    3022     *
    3023     * @param input the CharSequence to convert
    3024     * @param charset the charset to use, null means platform default
    3025     * @return an input stream
    3026     * @since 2.3
    3027     */
    3028    public static InputStream toInputStream(final CharSequence input, final Charset charset) {
    3029        return toInputStream(input.toString(), charset);
    3030    }
    3031
    3032    /**
    3033     * Converts the specified CharSequence to an input stream, encoded as bytes
    3034     * using the specified character encoding.
    3035     * <p>
    3036     * Character encoding names can be found at
    3037     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    3038     * </p>
    3039     *
    3040     * @param input the CharSequence to convert
    3041     * @param charsetName the name of the requested charset, null means platform default
    3042     * @return an input stream
    3043     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
    3044     *                                                      .UnsupportedEncodingException} in version 2.2 if the
    3045     *                                                      encoding is not supported.
    3046     * @since 2.0
    3047     */
    3048    public static InputStream toInputStream(final CharSequence input, final String charsetName) {
    3049        return toInputStream(input, Charsets.toCharset(charsetName));
    3050    }
    3051
    3052    /**
    3053     * Converts the specified string to an input stream, encoded as bytes
    3054     * using the default character encoding of the platform.
    3055     *
    3056     * @param input the string to convert
    3057     * @return an input stream
    3058     * @since 1.1
    3059     * @deprecated 2.5 use {@link #toInputStream(String, Charset)} instead
    3060     */
    3061    @Deprecated
    3062    public static InputStream toInputStream(final String input) {
    3063        return toInputStream(input, Charset.defaultCharset());
    3064    }
    3065
    3066    /**
    3067     * Converts the specified string to an input stream, encoded as bytes
    3068     * using the specified character encoding.
    3069     *
    3070     * @param input the string to convert
    3071     * @param charset the charset to use, null means platform default
    3072     * @return an input stream
    3073     * @since 2.3
    3074     */
    3075    public static InputStream toInputStream(final String input, final Charset charset) {
    3076        return new ByteArrayInputStream(input.getBytes(Charsets.toCharset(charset)));
    3077    }
    3078
    3079    /**
    3080     * Converts the specified string to an input stream, encoded as bytes
    3081     * using the specified character encoding.
    3082     * <p>
    3083     * Character encoding names can be found at
    3084     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    3085     * </p>
    3086     *
    3087     * @param input the string to convert
    3088     * @param charsetName the name of the requested charset, null means platform default
    3089     * @return an input stream
    3090     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
    3091     *                                                      .UnsupportedEncodingException} in version 2.2 if the
    3092     *                                                      encoding is not supported.
    3093     * @since 1.1
    3094     */
    3095    public static InputStream toInputStream(final String input, final String charsetName) {
    3096        return new ByteArrayInputStream(input.getBytes(Charsets.toCharset(charsetName)));
    3097    }
    3098
    3099    /**
    3100     * Gets the contents of a {@code byte[]} as a String
    3101     * using the default character encoding of the platform.
    3102     *
    3103     * @param input the byte array to read
    3104     * @return the requested String
    3105     * @throws NullPointerException if the input is null
    3106     * @deprecated 2.5 Use {@link String#String(byte[])} instead
    3107     */
    3108    @Deprecated
    3109    public static String toString(final byte[] input) {
    3110        // make explicit the use of the default charset
    3111        return new String(input, Charset.defaultCharset());
    3112    }
    3113
    3114    /**
    3115     * Gets the contents of a {@code byte[]} as a String
    3116     * using the specified character encoding.
    3117     * <p>
    3118     * Character encoding names can be found at
    3119     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    3120     * </p>
    3121     *
    3122     * @param input the byte array to read
    3123     * @param charsetName the name of the requested charset, null means platform default
    3124     * @return the requested String
    3125     * @throws NullPointerException if the input is null
    3126     */
    3127    public static String toString(final byte[] input, final String charsetName) {
    3128        return new String(input, Charsets.toCharset(charsetName));
    3129    }
    3130
    3131    /**
    3132     * Gets the contents of an {@link InputStream} as a String
    3133     * using the default character encoding of the platform.
    3134     * <p>
    3135     * This method buffers the input internally, so there is no need to use a
    3136     * {@link BufferedInputStream}.
    3137     * </p>
    3138     *
    3139     * @param input the {@link InputStream} to read
    3140     * @return the requested String
    3141     * @throws NullPointerException if the input is null
    3142     * @throws IOException          if an I/O error occurs
    3143     * @deprecated 2.5 use {@link #toString(InputStream, Charset)} instead
    3144     */
    3145    @Deprecated
    3146    public static String toString(final InputStream input) throws IOException {
    3147        return toString(input, Charset.defaultCharset());
    3148    }
    3149
    3150    /**
    3151     * Gets the contents of an {@link InputStream} as a String
    3152     * using the specified character encoding.
    3153     * <p>
    3154     * This method buffers the input internally, so there is no need to use a
    3155     * {@link BufferedInputStream}.
    3156     * </p>
    3157     *
    3158     * @param input the {@link InputStream} to read
    3159     * @param charset the charset to use, null means platform default
    3160     * @return the requested String
    3161     * @throws NullPointerException if the input is null
    3162     * @throws IOException          if an I/O error occurs
    3163     * @since 2.3
    3164     */
    3165    public static String toString(final InputStream input, final Charset charset) throws IOException {
    3166        try (StringBuilderWriter sw = new StringBuilderWriter()) {
    3167            copy(input, sw, charset);
    3168            return sw.toString();
    3169        }
    3170    }
    3171
    3172    /**
    3173     * Gets the contents of an {@link InputStream} as a String
    3174     * using the specified character encoding.
    3175     * <p>
    3176     * Character encoding names can be found at
    3177     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    3178     * </p>
    3179     * <p>
    3180     * This method buffers the input internally, so there is no need to use a
    3181     * {@link BufferedInputStream}.
    3182     * </p>
    3183     *
    3184     * @param input the {@link InputStream} to read
    3185     * @param charsetName the name of the requested charset, null means platform default
    3186     * @return the requested String
    3187     * @throws NullPointerException                         if the input is null
    3188     * @throws IOException                                  if an I/O error occurs
    3189     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
    3190     *                                                      .UnsupportedEncodingException} in version 2.2 if the
    3191     *                                                      encoding is not supported.
    3192     */
    3193    public static String toString(final InputStream input, final String charsetName)
    3194            throws IOException {
    3195        return toString(input, Charsets.toCharset(charsetName));
    3196    }
    3197
    3198    /**
    3199     * Gets the contents of an {@link InputStream} from a supplier as a String
    3200     * using the specified character encoding.
    3201     * <p>
    3202     * This method buffers the input internally, so there is no need to use a
    3203     * {@link BufferedInputStream}.
    3204     * </p>
    3205     *
    3206     * @param input supplies the {@link InputStream} to read
    3207     * @param charset the charset to use, null means platform default
    3208     * @return the requested String
    3209     * @throws NullPointerException if the input is null
    3210     * @throws IOException          if an I/O error occurs
    3211     * @since 2.12.0
    3212     */
    3213    public static String toString(final IOSupplier<InputStream> input, final Charset charset) throws IOException {
    3214        return toString(input, charset, () -> {
    3215            throw new NullPointerException("input");
    3216        });
    3217    }
    3218
    3219    /**
    3220     * Gets the contents of an {@link InputStream} from a supplier as a String
    3221     * using the specified character encoding.
    3222     * <p>
    3223     * This method buffers the input internally, so there is no need to use a
    3224     * {@link BufferedInputStream}.
    3225     * </p>
    3226     *
    3227     * @param input supplies the {@link InputStream} to read
    3228     * @param charset the charset to use, null means platform default
    3229     * @param defaultString the default return value if the supplier or its value is null.
    3230     * @return the requested String
    3231     * @throws NullPointerException if the input is null
    3232     * @throws IOException          if an I/O error occurs
    3233     * @since 2.12.0
    3234     */
    3235    public static String toString(final IOSupplier<InputStream> input, final Charset charset, final IOSupplier<String> defaultString) throws IOException {
    3236        if (input == null) {
    3237            return defaultString.get();
    3238        }
    3239        try (InputStream inputStream = input.get()) {
    3240            return inputStream != null ? toString(inputStream, charset) : defaultString.get();
    3241        }
    3242    }
    3243
    3244    /**
    3245     * Gets the contents of a {@link Reader} as a String.
    3246     * <p>
    3247     * This method buffers the input internally, so there is no need to use a
    3248     * {@link BufferedReader}.
    3249     * </p>
    3250     *
    3251     * @param reader the {@link Reader} to read
    3252     * @return the requested String
    3253     * @throws NullPointerException if the input is null
    3254     * @throws IOException          if an I/O error occurs
    3255     */
    3256    public static String toString(final Reader reader) throws IOException {
    3257        try (StringBuilderWriter sw = new StringBuilderWriter()) {
    3258            copy(reader, sw);
    3259            return sw.toString();
    3260        }
    3261    }
    3262
    3263    /**
    3264     * Gets the contents at the given URI.
    3265     *
    3266     * @param uri The URI source.
    3267     * @return The contents of the URL as a String.
    3268     * @throws IOException if an I/O exception occurs.
    3269     * @since 2.1
    3270     * @deprecated 2.5 use {@link #toString(URI, Charset)} instead
    3271     */
    3272    @Deprecated
    3273    public static String toString(final URI uri) throws IOException {
    3274        return toString(uri, Charset.defaultCharset());
    3275    }
    3276
    3277    /**
    3278     * Gets the contents at the given URI.
    3279     *
    3280     * @param uri The URI source.
    3281     * @param encoding The encoding name for the URL contents.
    3282     * @return The contents of the URL as a String.
    3283     * @throws IOException if an I/O exception occurs.
    3284     * @since 2.3.
    3285     */
    3286    public static String toString(final URI uri, final Charset encoding) throws IOException {
    3287        return toString(uri.toURL(), Charsets.toCharset(encoding));
    3288    }
    3289
    3290    /**
    3291     * Gets the contents at the given URI.
    3292     *
    3293     * @param uri The URI source.
    3294     * @param charsetName The encoding name for the URL contents.
    3295     * @return The contents of the URL as a String.
    3296     * @throws IOException                                  if an I/O exception occurs.
    3297     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
    3298     *                                                      .UnsupportedEncodingException} in version 2.2 if the
    3299     *                                                      encoding is not supported.
    3300     * @since 2.1
    3301     */
    3302    public static String toString(final URI uri, final String charsetName) throws IOException {
    3303        return toString(uri, Charsets.toCharset(charsetName));
    3304    }
    3305
    3306    /**
    3307     * Gets the contents at the given URL.
    3308     *
    3309     * @param url The URL source.
    3310     * @return The contents of the URL as a String.
    3311     * @throws IOException if an I/O exception occurs.
    3312     * @since 2.1
    3313     * @deprecated 2.5 use {@link #toString(URL, Charset)} instead
    3314     */
    3315    @Deprecated
    3316    public static String toString(final URL url) throws IOException {
    3317        return toString(url, Charset.defaultCharset());
    3318    }
    3319
    3320    /**
    3321     * Gets the contents at the given URL.
    3322     *
    3323     * @param url The URL source.
    3324     * @param encoding The encoding name for the URL contents.
    3325     * @return The contents of the URL as a String.
    3326     * @throws IOException if an I/O exception occurs.
    3327     * @since 2.3
    3328     */
    3329    public static String toString(final URL url, final Charset encoding) throws IOException {
    3330        return toString(url::openStream, encoding);
    3331    }
    3332
    3333    /**
    3334     * Gets the contents at the given URL.
    3335     *
    3336     * @param url The URL source.
    3337     * @param charsetName The encoding name for the URL contents.
    3338     * @return The contents of the URL as a String.
    3339     * @throws IOException                                  if an I/O exception occurs.
    3340     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
    3341     *                                                      .UnsupportedEncodingException} in version 2.2 if the
    3342     *                                                      encoding is not supported.
    3343     * @since 2.1
    3344     */
    3345    public static String toString(final URL url, final String charsetName) throws IOException {
    3346        return toString(url, Charsets.toCharset(charsetName));
    3347    }
    3348
    3349    /**
    3350     * Writes bytes from a {@code byte[]} to an {@link OutputStream}.
    3351     *
    3352     * @param data the byte array to write, do not modify during output,
    3353     * null ignored
    3354     * @param output the {@link OutputStream} to write to
    3355     * @throws NullPointerException if output is null
    3356     * @throws IOException          if an I/O error occurs
    3357     * @since 1.1
    3358     */
    3359    public static void write(final byte[] data, final OutputStream output)
    3360            throws IOException {
    3361        if (data != null) {
    3362            output.write(data);
    3363        }
    3364    }
    3365
    3366    /**
    3367     * Writes bytes from a {@code byte[]} to chars on a {@link Writer}
    3368     * using the default character encoding of the platform.
    3369     * <p>
    3370     * This method uses {@link String#String(byte[])}.
    3371     * </p>
    3372     *
    3373     * @param data the byte array to write, do not modify during output,
    3374     * null ignored
    3375     * @param writer the {@link Writer} to write to
    3376     * @throws NullPointerException if output is null
    3377     * @throws IOException          if an I/O error occurs
    3378     * @since 1.1
    3379     * @deprecated 2.5 use {@link #write(byte[], Writer, Charset)} instead
    3380     */
    3381    @Deprecated
    3382    public static void write(final byte[] data, final Writer writer) throws IOException {
    3383        write(data, writer, Charset.defaultCharset());
    3384    }
    3385
    3386    /**
    3387     * Writes bytes from a {@code byte[]} to chars on a {@link Writer}
    3388     * using the specified character encoding.
    3389     * <p>
    3390     * This method uses {@link String#String(byte[], String)}.
    3391     * </p>
    3392     *
    3393     * @param data the byte array to write, do not modify during output,
    3394     * null ignored
    3395     * @param writer the {@link Writer} to write to
    3396     * @param charset the charset to use, null means platform default
    3397     * @throws NullPointerException if output is null
    3398     * @throws IOException          if an I/O error occurs
    3399     * @since 2.3
    3400     */
    3401    public static void write(final byte[] data, final Writer writer, final Charset charset) throws IOException {
    3402        if (data != null) {
    3403            writer.write(new String(data, Charsets.toCharset(charset)));
    3404        }
    3405    }
    3406
    3407    /**
    3408     * Writes bytes from a {@code byte[]} to chars on a {@link Writer}
    3409     * using the specified character encoding.
    3410     * <p>
    3411     * Character encoding names can be found at
    3412     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    3413     * </p>
    3414     * <p>
    3415     * This method uses {@link String#String(byte[], String)}.
    3416     * </p>
    3417     *
    3418     * @param data the byte array to write, do not modify during output,
    3419     * null ignored
    3420     * @param writer the {@link Writer} to write to
    3421     * @param charsetName the name of the requested charset, null means platform default
    3422     * @throws NullPointerException                         if output is null
    3423     * @throws IOException                                  if an I/O error occurs
    3424     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
    3425     *                                                      .UnsupportedEncodingException} in version 2.2 if the
    3426     *                                                      encoding is not supported.
    3427     * @since 1.1
    3428     */
    3429    public static void write(final byte[] data, final Writer writer, final String charsetName) throws IOException {
    3430        write(data, writer, Charsets.toCharset(charsetName));
    3431    }
    3432
    3433    /**
    3434     * Writes chars from a {@code char[]} to bytes on an
    3435     * {@link OutputStream}.
    3436     * <p>
    3437     * This method uses {@link String#String(char[])} and
    3438     * {@link String#getBytes()}.
    3439     * </p>
    3440     *
    3441     * @param data the char array to write, do not modify during output,
    3442     * null ignored
    3443     * @param output the {@link OutputStream} to write to
    3444     * @throws NullPointerException if output is null
    3445     * @throws IOException          if an I/O error occurs
    3446     * @since 1.1
    3447     * @deprecated 2.5 use {@link #write(char[], OutputStream, Charset)} instead
    3448     */
    3449    @Deprecated
    3450    public static void write(final char[] data, final OutputStream output)
    3451            throws IOException {
    3452        write(data, output, Charset.defaultCharset());
    3453    }
    3454
    3455    /**
    3456     * Writes chars from a {@code char[]} to bytes on an
    3457     * {@link OutputStream} using the specified character encoding.
    3458     * <p>
    3459     * This method uses {@link String#String(char[])} and
    3460     * {@link String#getBytes(String)}.
    3461     * </p>
    3462     *
    3463     * @param data the char array to write, do not modify during output,
    3464     * null ignored
    3465     * @param output the {@link OutputStream} to write to
    3466     * @param charset the charset to use, null means platform default
    3467     * @throws NullPointerException if output is null
    3468     * @throws IOException          if an I/O error occurs
    3469     * @since 2.3
    3470     */
    3471    public static void write(final char[] data, final OutputStream output, final Charset charset) throws IOException {
    3472        if (data != null) {
    3473            write(new String(data), output, charset);
    3474        }
    3475    }
    3476
    3477    /**
    3478     * Writes chars from a {@code char[]} to bytes on an
    3479     * {@link OutputStream} using the specified character encoding.
    3480     * <p>
    3481     * Character encoding names can be found at
    3482     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    3483     * </p>
    3484     * <p>
    3485     * This method uses {@link String#String(char[])} and
    3486     * {@link String#getBytes(String)}.
    3487     * </p>
    3488     *
    3489     * @param data the char array to write, do not modify during output,
    3490     * null ignored
    3491     * @param output the {@link OutputStream} to write to
    3492     * @param charsetName the name of the requested charset, null means platform default
    3493     * @throws NullPointerException                         if output is null
    3494     * @throws IOException                                  if an I/O error occurs
    3495     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
    3496     * .UnsupportedEncodingException} in version 2.2 if the encoding is not supported.
    3497     * @since 1.1
    3498     */
    3499    public static void write(final char[] data, final OutputStream output, final String charsetName)
    3500            throws IOException {
    3501        write(data, output, Charsets.toCharset(charsetName));
    3502    }
    3503
    3504    /**
    3505     * Writes chars from a {@code char[]} to a {@link Writer}
    3506     *
    3507     * @param data the char array to write, do not modify during output,
    3508     * null ignored
    3509     * @param writer the {@link Writer} to write to
    3510     * @throws NullPointerException if output is null
    3511     * @throws IOException          if an I/O error occurs
    3512     * @since 1.1
    3513     */
    3514    public static void write(final char[] data, final Writer writer) throws IOException {
    3515        if (data != null) {
    3516            writer.write(data);
    3517        }
    3518    }
    3519
    3520    /**
    3521     * Writes chars from a {@link CharSequence} to bytes on an
    3522     * {@link OutputStream} using the default character encoding of the
    3523     * platform.
    3524     * <p>
    3525     * This method uses {@link String#getBytes()}.
    3526     * </p>
    3527     *
    3528     * @param data the {@link CharSequence} to write, null ignored
    3529     * @param output the {@link OutputStream} to write to
    3530     * @throws NullPointerException if output is null
    3531     * @throws IOException          if an I/O error occurs
    3532     * @since 2.0
    3533     * @deprecated 2.5 use {@link #write(CharSequence, OutputStream, Charset)} instead
    3534     */
    3535    @Deprecated
    3536    public static void write(final CharSequence data, final OutputStream output)
    3537            throws IOException {
    3538        write(data, output, Charset.defaultCharset());
    3539    }
    3540
    3541    /**
    3542     * Writes chars from a {@link CharSequence} to bytes on an
    3543     * {@link OutputStream} using the specified character encoding.
    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 charset the charset to use, null means platform default
    3551     * @throws NullPointerException if output is null
    3552     * @throws IOException          if an I/O error occurs
    3553     * @since 2.3
    3554     */
    3555    public static void write(final CharSequence data, final OutputStream output, final Charset charset)
    3556            throws IOException {
    3557        if (data != null) {
    3558            write(data.toString(), output, charset);
    3559        }
    3560    }
    3561
    3562    /**
    3563     * Writes chars from a {@link CharSequence} to bytes on an
    3564     * {@link OutputStream} using the specified character encoding.
    3565     * <p>
    3566     * Character encoding names can be found at
    3567     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    3568     * </p>
    3569     * <p>
    3570     * This method uses {@link String#getBytes(String)}.
    3571     * </p>
    3572     *
    3573     * @param data the {@link CharSequence} to write, null ignored
    3574     * @param output the {@link OutputStream} to write to
    3575     * @param charsetName the name of the requested charset, null means platform default
    3576     * @throws NullPointerException        if output is null
    3577     * @throws IOException                 if an I/O error occurs
    3578     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
    3579     * .UnsupportedEncodingException} in version 2.2 if the encoding is not supported.
    3580     * @since 2.0
    3581     */
    3582    public static void write(final CharSequence data, final OutputStream output, final String charsetName)
    3583            throws IOException {
    3584        write(data, output, Charsets.toCharset(charsetName));
    3585    }
    3586
    3587
    3588    /**
    3589     * Writes chars from a {@link CharSequence} to a {@link Writer}.
    3590     *
    3591     * @param data the {@link CharSequence} to write, null ignored
    3592     * @param writer the {@link Writer} to write to
    3593     * @throws NullPointerException if output is null
    3594     * @throws IOException          if an I/O error occurs
    3595     * @since 2.0
    3596     */
    3597    public static void write(final CharSequence data, final Writer writer) throws IOException {
    3598        if (data != null) {
    3599            write(data.toString(), writer);
    3600        }
    3601    }
    3602
    3603    /**
    3604     * Writes chars from a {@link String} to bytes on an
    3605     * {@link OutputStream} using the default character encoding of the
    3606     * platform.
    3607     * <p>
    3608     * This method uses {@link String#getBytes()}.
    3609     * </p>
    3610     *
    3611     * @param data the {@link String} to write, null ignored
    3612     * @param output the {@link OutputStream} to write to
    3613     * @throws NullPointerException if output is null
    3614     * @throws IOException          if an I/O error occurs
    3615     * @since 1.1
    3616     * @deprecated 2.5 use {@link #write(String, OutputStream, Charset)} instead
    3617     */
    3618    @Deprecated
    3619    public static void write(final String data, final OutputStream output)
    3620            throws IOException {
    3621        write(data, output, Charset.defaultCharset());
    3622    }
    3623
    3624    /**
    3625     * Writes chars from a {@link String} to bytes on an
    3626     * {@link OutputStream} using the specified character encoding.
    3627     * <p>
    3628     * This method uses {@link String#getBytes(String)}.
    3629     * </p>
    3630     *
    3631     * @param data the {@link String} to write, null ignored
    3632     * @param output the {@link OutputStream} to write to
    3633     * @param charset the charset to use, null means platform default
    3634     * @throws NullPointerException if output is null
    3635     * @throws IOException          if an I/O error occurs
    3636     * @since 2.3
    3637     */
    3638    @SuppressWarnings("resource")
    3639    public static void write(final String data, final OutputStream output, final Charset charset) throws IOException {
    3640        if (data != null) {
    3641            // Use Charset#encode(String), since calling String#getBytes(Charset) might result in
    3642            // NegativeArraySizeException or OutOfMemoryError.
    3643            // The underlying OutputStream should not be closed, so the channel is not closed.
    3644            Channels.newChannel(output).write(Charsets.toCharset(charset).encode(data));
    3645        }
    3646    }
    3647
    3648    /**
    3649     * Writes chars from a {@link String} to bytes on an
    3650     * {@link OutputStream} using the specified character encoding.
    3651     * <p>
    3652     * Character encoding names can be found at
    3653     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    3654     * </p>
    3655     * <p>
    3656     * This method uses {@link String#getBytes(String)}.
    3657     * </p>
    3658     *
    3659     * @param data the {@link String} to write, null ignored
    3660     * @param output the {@link OutputStream} to write to
    3661     * @param charsetName the name of the requested charset, null means platform default
    3662     * @throws NullPointerException        if output is null
    3663     * @throws IOException                 if an I/O error occurs
    3664     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
    3665     * .UnsupportedEncodingException} in version 2.2 if the encoding is not supported.
    3666     * @since 1.1
    3667     */
    3668    public static void write(final String data, final OutputStream output, final String charsetName)
    3669            throws IOException {
    3670        write(data, output, Charsets.toCharset(charsetName));
    3671    }
    3672
    3673    /**
    3674     * Writes chars from a {@link String} to a {@link Writer}.
    3675     *
    3676     * @param data the {@link String} to write, null ignored
    3677     * @param writer the {@link Writer} to write to
    3678     * @throws NullPointerException if output is null
    3679     * @throws IOException          if an I/O error occurs
    3680     * @since 1.1
    3681     */
    3682    public static void write(final String data, final Writer writer) throws IOException {
    3683        if (data != null) {
    3684            writer.write(data);
    3685        }
    3686    }
    3687
    3688    /**
    3689     * Writes chars from a {@link StringBuffer} to bytes on an
    3690     * {@link OutputStream} using the default character encoding of the
    3691     * platform.
    3692     * <p>
    3693     * This method uses {@link String#getBytes()}.
    3694     * </p>
    3695     *
    3696     * @param data the {@link StringBuffer} to write, null ignored
    3697     * @param output the {@link OutputStream} to write to
    3698     * @throws NullPointerException if output is null
    3699     * @throws IOException          if an I/O error occurs
    3700     * @since 1.1
    3701     * @deprecated Use {@link #write(CharSequence, OutputStream)}
    3702     */
    3703    @Deprecated
    3704    public static void write(final StringBuffer data, final OutputStream output) //NOSONAR
    3705            throws IOException {
    3706        write(data, output, (String) null);
    3707    }
    3708
    3709    /**
    3710     * Writes chars from a {@link StringBuffer} to bytes on an
    3711     * {@link OutputStream} using the specified character encoding.
    3712     * <p>
    3713     * Character encoding names can be found at
    3714     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    3715     * </p>
    3716     * <p>
    3717     * This method uses {@link String#getBytes(String)}.
    3718     * </p>
    3719     *
    3720     * @param data the {@link StringBuffer} to write, null ignored
    3721     * @param output the {@link OutputStream} to write to
    3722     * @param charsetName the name of the requested charset, null means platform default
    3723     * @throws NullPointerException        if output is null
    3724     * @throws IOException                 if an I/O error occurs
    3725     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
    3726     * .UnsupportedEncodingException} in version 2.2 if the encoding is not supported.
    3727     * @since 1.1
    3728     * @deprecated Use {@link #write(CharSequence, OutputStream, String)}.
    3729     */
    3730    @Deprecated
    3731    public static void write(final StringBuffer data, final OutputStream output, final String charsetName) //NOSONAR
    3732        throws IOException {
    3733        if (data != null) {
    3734            write(data.toString(), output, Charsets.toCharset(charsetName));
    3735        }
    3736    }
    3737
    3738    /**
    3739     * Writes chars from a {@link StringBuffer} to a {@link Writer}.
    3740     *
    3741     * @param data the {@link StringBuffer} to write, null ignored
    3742     * @param writer the {@link Writer} to write to
    3743     * @throws NullPointerException if output is null
    3744     * @throws IOException          if an I/O error occurs
    3745     * @since 1.1
    3746     * @deprecated Use {@link #write(CharSequence, Writer)}
    3747     */
    3748    @Deprecated
    3749    public static void write(final StringBuffer data, final Writer writer) //NOSONAR
    3750            throws IOException {
    3751        if (data != null) {
    3752            writer.write(data.toString());
    3753        }
    3754    }
    3755
    3756    /**
    3757     * Writes bytes from a {@code byte[]} to an {@link OutputStream} using chunked writes.
    3758     * This is intended for writing very large byte arrays which might otherwise cause excessive
    3759     * memory usage if the native code has to allocate a copy.
    3760     *
    3761     * @param data the byte array to write, do not modify during output,
    3762     * null ignored
    3763     * @param output the {@link OutputStream} to write to
    3764     * @throws NullPointerException if output is null
    3765     * @throws IOException          if an I/O error occurs
    3766     * @since 2.5
    3767     */
    3768    public static void writeChunked(final byte[] data, final OutputStream output)
    3769            throws IOException {
    3770        if (data != null) {
    3771            int bytes = data.length;
    3772            int offset = 0;
    3773            while (bytes > 0) {
    3774                final int chunk = Math.min(bytes, DEFAULT_BUFFER_SIZE);
    3775                output.write(data, offset, chunk);
    3776                bytes -= chunk;
    3777                offset += chunk;
    3778            }
    3779        }
    3780    }
    3781
    3782    /**
    3783     * Writes chars from a {@code char[]} to a {@link Writer} using chunked writes.
    3784     * This is intended for writing very large byte arrays which might otherwise cause excessive
    3785     * memory usage if the native code has to allocate a copy.
    3786     *
    3787     * @param data the char array to write, do not modify during output,
    3788     * null ignored
    3789     * @param writer the {@link Writer} to write to
    3790     * @throws NullPointerException if output is null
    3791     * @throws IOException          if an I/O error occurs
    3792     * @since 2.5
    3793     */
    3794    public static void writeChunked(final char[] data, final Writer writer) throws IOException {
    3795        if (data != null) {
    3796            int bytes = data.length;
    3797            int offset = 0;
    3798            while (bytes > 0) {
    3799                final int chunk = Math.min(bytes, DEFAULT_BUFFER_SIZE);
    3800                writer.write(data, offset, chunk);
    3801                bytes -= chunk;
    3802                offset += chunk;
    3803            }
    3804        }
    3805    }
    3806
    3807    /**
    3808     * Writes the {@link #toString()} value of each item in a collection to
    3809     * an {@link OutputStream} line by line, using the default character
    3810     * encoding of the platform and the specified line ending.
    3811     *
    3812     * @param lines the lines to write, null entries produce blank lines
    3813     * @param lineEnding the line separator to use, null is system default
    3814     * @param output the {@link OutputStream} to write to, not null, not closed
    3815     * @throws NullPointerException if the output is null
    3816     * @throws IOException          if an I/O error occurs
    3817     * @since 1.1
    3818     * @deprecated 2.5 use {@link #writeLines(Collection, String, OutputStream, Charset)} instead
    3819     */
    3820    @Deprecated
    3821    public static void writeLines(final Collection<?> lines, final String lineEnding,
    3822                                  final OutputStream output) throws IOException {
    3823        writeLines(lines, lineEnding, output, Charset.defaultCharset());
    3824    }
    3825
    3826    /**
    3827     * Writes the {@link #toString()} value of each item in a collection to
    3828     * an {@link OutputStream} line by line, using the specified character
    3829     * encoding and the specified line ending.
    3830     * <p>
    3831     * UTF-16 is written big-endian with no byte order mark.
    3832     * For little endian, use UTF-16LE. For a BOM, write it to the stream
    3833     * before calling this method.
    3834     * </p>
    3835     *
    3836     * @param lines the lines to write, null entries produce blank lines
    3837     * @param lineEnding the line separator to use, null is system default
    3838     * @param output the {@link OutputStream} to write to, not null, not closed
    3839     * @param charset the charset to use, null means platform default
    3840     * @throws NullPointerException if output is null
    3841     * @throws IOException          if an I/O error occurs
    3842     * @since 2.3
    3843     */
    3844    public static void writeLines(final Collection<?> lines, String lineEnding, final OutputStream output,
    3845            Charset charset) throws IOException {
    3846        if (lines == null) {
    3847            return;
    3848        }
    3849        if (lineEnding == null) {
    3850            lineEnding = System.lineSeparator();
    3851        }
    3852        if (StandardCharsets.UTF_16.equals(charset)) {
    3853            // don't write a BOM
    3854            charset = StandardCharsets.UTF_16BE;
    3855        }
    3856        final byte[] eolBytes = lineEnding.getBytes(charset);
    3857        for (final Object line : lines) {
    3858            if (line != null) {
    3859                write(line.toString(), output, charset);
    3860            }
    3861            output.write(eolBytes);
    3862        }
    3863    }
    3864
    3865    /**
    3866     * Writes the {@link #toString()} value of each item in a collection to
    3867     * an {@link OutputStream} line by line, using the specified character
    3868     * encoding and the specified line ending.
    3869     * <p>
    3870     * Character encoding names can be found at
    3871     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    3872     * </p>
    3873     *
    3874     * @param lines the lines to write, null entries produce blank lines
    3875     * @param lineEnding the line separator to use, null is system default
    3876     * @param output the {@link OutputStream} to write to, not null, not closed
    3877     * @param charsetName the name of the requested charset, null means platform default
    3878     * @throws NullPointerException                         if the output is null
    3879     * @throws IOException                                  if an I/O error occurs
    3880     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
    3881     *                                                      .UnsupportedEncodingException} in version 2.2 if the
    3882     *                                                      encoding is not supported.
    3883     * @since 1.1
    3884     */
    3885    public static void writeLines(final Collection<?> lines, final String lineEnding,
    3886                                  final OutputStream output, final String charsetName) throws IOException {
    3887        writeLines(lines, lineEnding, output, Charsets.toCharset(charsetName));
    3888    }
    3889
    3890    /**
    3891     * Writes the {@link #toString()} value of each item in a collection to
    3892     * a {@link Writer} line by line, using the specified line ending.
    3893     *
    3894     * @param lines the lines to write, null entries produce blank lines
    3895     * @param lineEnding the line separator to use, null is system default
    3896     * @param writer the {@link Writer} to write to, not null, not closed
    3897     * @throws NullPointerException if the input is null
    3898     * @throws IOException          if an I/O error occurs
    3899     * @since 1.1
    3900     */
    3901    public static void writeLines(final Collection<?> lines, String lineEnding,
    3902                                  final Writer writer) throws IOException {
    3903        if (lines == null) {
    3904            return;
    3905        }
    3906        if (lineEnding == null) {
    3907            lineEnding = System.lineSeparator();
    3908        }
    3909        for (final Object line : lines) {
    3910            if (line != null) {
    3911                writer.write(line.toString());
    3912            }
    3913            writer.write(lineEnding);
    3914        }
    3915    }
    3916
    3917    /**
    3918     * Returns the given Appendable if it is already a {@link Writer}, otherwise creates a Writer wrapper around the
    3919     * given Appendable.
    3920     *
    3921     * @param appendable the Appendable to wrap or return (not null)
    3922     * @return  the given Appendable or a Writer wrapper around the given Appendable
    3923     * @throws NullPointerException if the input parameter is null
    3924     * @since 2.7
    3925     */
    3926    public static Writer writer(final Appendable appendable) {
    3927        Objects.requireNonNull(appendable, "appendable");
    3928        if (appendable instanceof Writer) {
    3929            return (Writer) appendable;
    3930        }
    3931        if (appendable instanceof StringBuilder) {
    3932            return new StringBuilderWriter((StringBuilder) appendable);
    3933        }
    3934        return new AppendableWriter<>(appendable);
    3935    }
    3936
    3937    /**
    3938     * Instances should NOT be constructed in standard programming.
    3939     * @deprecated Will be private in 3.0.
    3940     */
    3941    @Deprecated
    3942    public IOUtils() { //NOSONAR
    3943    }
    3944
    3945}