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