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