    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     */
    017    package org.apache.commons.io;
    018
    019    import java.io.BufferedInputStream;
    020    import java.io.BufferedReader;
    021    import java.io.ByteArrayInputStream;
    022    import java.io.CharArrayWriter;
    023    import java.io.Closeable;
    024    import java.io.EOFException;
    025    import java.io.File;
    026    import java.io.IOException;
    027    import java.io.InputStream;
    028    import java.io.InputStreamReader;
    029    import java.io.OutputStream;
    030    import java.io.OutputStreamWriter;
    031    import java.io.PrintWriter;
    032    import java.io.Reader;
    033    import java.io.Writer;
    034    import java.net.Socket;
    035    import java.util.ArrayList;
    036    import java.util.Collection;
    037    import java.util.List;
    038
    039    import org.apache.commons.io.output.ByteArrayOutputStream;
    040    import org.apache.commons.io.output.StringBuilderWriter;
    041
    042    /**
    043     * General IO stream manipulation utilities.
    044     * <p>
    045     * This class provides static utility methods for input/output operations.
    046     * <ul>
    047     * <li>closeQuietly - these methods close a stream ignoring nulls and exceptions
    048     * <li>toXxx/read - these methods read data from a stream
    049     * <li>write - these methods write data to a stream
    050     * <li>copy - these methods copy all the data from one stream to another
    051     * <li>contentEquals - these methods compare the content of two streams
    052     * </ul>
    053     * <p>
    054     * The byte-to-char methods and char-to-byte methods involve a conversion step.
    055     * Two methods are provided in each case, one that uses the platform default
    056     * encoding and the other which allows you to specify an encoding. You are
    057     * encouraged to always specify an encoding because relying on the platform
    058     * default can lead to unexpected results, for example when moving from
    059     * development to production.
    060     * <p>
    061     * All the methods in this class that read a stream are buffered internally.
    062     * This means that there is no cause to use a <code>BufferedInputStream</code>
    063     * or <code>BufferedReader</code>. The default buffer size of 4K has been shown
    064     * to be efficient in tests.
    065     * <p>
    066     * Wherever possible, the methods in this class do <em>not</em> flush or close
    067     * the stream. This is to avoid making non-portable assumptions about the
    068     * streams' origin and further use. Thus the caller is still responsible for
    069     * closing streams after use.
    070     * <p>
    071     * Origin of code: Excalibur.
    072     *
    073     * @author Peter Donald
    074     * @author Jeff Turner
    075     * @author Matthew Hawthorne
    076     * @author Stephen Colebourne
    077     * @author Gareth Davis
    078     * @author Ian Springer
    079     * @author Niall Pemberton
    080     * @author Sandy McArthur
    081     * @version $Id: IOUtils.java 1003721 2010-10-02 00:42:31Z niallp $
    082     */
    083    public class IOUtils {
    084        // NOTE: This class is focussed on InputStream, OutputStream, Reader and
    085        // Writer. Each method should take at least one of these as a parameter,
    086        // or return one of them.
    087
    088        /**
    089         * The Unix directory separator character.
    090         */
    091        public static final char DIR_SEPARATOR_UNIX = '/';
    092        /**
    093         * The Windows directory separator character.
    094         */
    095        public static final char DIR_SEPARATOR_WINDOWS = '\\';
    096        /**
    097         * The system directory separator character.
    098         */
    099        public static final char DIR_SEPARATOR = File.separatorChar;
    100        /**
    101         * The Unix line separator string.
    102         */
    103        public static final String LINE_SEPARATOR_UNIX = "\n";
    104        /**
    105         * The Windows line separator string.
    106         */
    107        public static final String LINE_SEPARATOR_WINDOWS = "\r\n";
    108        /**
    109         * The system line separator string.
    110         */
    111        public static final String LINE_SEPARATOR;
    112        static {
    113            // avoid security issues
    114            StringBuilderWriter buf = new StringBuilderWriter(4);
    115            PrintWriter out = new PrintWriter(buf);
    116            out.println();
    117            LINE_SEPARATOR = buf.toString();
    118            out.close();
    119        }
    120
    121        /**
    122         * The default buffer size to use for
    123         * {@link #copyLarge(InputStream, OutputStream)}
    124         * and
    125         * {@link #copyLarge(Reader, Writer)}
    126         */
    127        private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
    128
    129        /**
    130         * The default buffer size to use for the skip() methods.
    131         */
    132        private static final int SKIP_BUFFER_SIZE = 2048;
    133
    134        // Allocated in the skip method if necessary.
    135        private static char[] SKIP_CHAR_BUFFER;
    136        private static byte[] SKIP_BYTE_BUFFER;
    137
    138        /**
    139         * Instances should NOT be constructed in standard programming.
    140         */
    141        public IOUtils() {
    142            super();
    143        }
    144
    145        //-----------------------------------------------------------------------
    146        /**
    147         * Unconditionally close an <code>Reader</code>.
    148         * <p>
    149         * Equivalent to {@link Reader#close()}, except any exceptions will be ignored.
    150         * This is typically used in finally blocks.
    151         * <p>
    152         * Example code:
    153         * <pre>
    154         *   char[] data = new char[1024];
    155         *   Reader in = null;
    156         *   try {
    157         *       in = new FileReader("foo.txt");
    158         *       in.read(data);
    159         *       in.close(); //close errors are handled
    160         *   } catch (Exception e) {
    161         *       // error handling
    162         *   } finally {
    163         *       IOUtils.closeQuietly(in);
    164         *   }
    165         * </pre>
    166         *
    167         * @param input  the Reader to close, may be null or already closed
    168         */
    169        public static void closeQuietly(Reader input) {
    170            closeQuietly((Closeable)input);
    171        }
    172
    173        /**
    174         * Unconditionally close a <code>Writer</code>.
    175         * <p>
    176         * Equivalent to {@link Writer#close()}, except any exceptions will be ignored.
    177         * This is typically used in finally blocks.
    178         * <p>
    179         * Example code:
    180         * <pre>
    181         *   Writer out = null;
    182         *   try {
    183         *       out = new StringWriter();
    184         *       out.write("Hello World");
    185         *       out.close(); //close errors are handled
    186         *   } catch (Exception e) {
    187         *       // error handling
    188         *   } finally {
    189         *       IOUtils.closeQuietly(out);
    190         *   }
    191         * </pre>
    192         *
    193         * @param output  the Writer to close, may be null or already closed
    194         */
    195        public static void closeQuietly(Writer output) {
    196            closeQuietly((Closeable)output);
    197        }
    198
    199        /**
    200         * Unconditionally close an <code>InputStream</code>.
    201         * <p>
    202         * Equivalent to {@link InputStream#close()}, except any exceptions will be ignored.
    203         * This is typically used in finally blocks.
    204         * <p>
    205         * Example code:
    206         * <pre>
    207         *   byte[] data = new byte[1024];
    208         *   InputStream in = null;
    209         *   try {
    210         *       in = new FileInputStream("foo.txt");
    211         *       in.read(data);
    212         *       in.close(); //close errors are handled
    213         *   } catch (Exception e) {
    214         *       // error handling
    215         *   } finally {
    216         *       IOUtils.closeQuietly(in);
    217         *   }
    218         * </pre>
    219         *
    220         * @param input  the InputStream to close, may be null or already closed
    221         */
    222        public static void closeQuietly(InputStream input) {
    223            closeQuietly((Closeable)input);
    224        }
    225
    226        /**
    227         * Unconditionally close an <code>OutputStream</code>.
    228         * <p>
    229         * Equivalent to {@link OutputStream#close()}, except any exceptions will be ignored.
    230         * This is typically used in finally blocks.
    231         * <p>
    232         * Example code:
    233         * <pre>
    234         * byte[] data = "Hello, World".getBytes();
    235         *
    236         * OutputStream out = null;
    237         * try {
    238         *     out = new FileOutputStream("foo.txt");
    239         *     out.write(data);
    240         *     out.close(); //close errors are handled
    241         * } catch (IOException e) {
    242         *     // error handling
    243         * } finally {
    244         *     IOUtils.closeQuietly(out);
    245         * }
    246         * </pre>
    247         *
    248         * @param output  the OutputStream to close, may be null or already closed
    249         */
    250        public static void closeQuietly(OutputStream output) {
    251            closeQuietly((Closeable)output);
    252        }
    253
    254        /**
    255         * Unconditionally close a <code>Closeable</code>.
    256         * <p>
    257         * Equivalent to {@link Closeable#close()}, except any exceptions will be ignored.
    258         * This is typically used in finally blocks.
    259         * <p>
    260         * Example code:
    261         * <pre>
    262         *   Closeable closeable = null;
    263         *   try {
    264         *       closeable = new FileReader("foo.txt");
    265         *       // process closeable
    266         *       closeable.close();
    267         *   } catch (Exception e) {
    268         *       // error handling
    269         *   } finally {
    270         *       IOUtils.closeQuietly(closeable);
    271         *   }
    272         * </pre>
    273         *
    274         * @param closeable the object to close, may be null or already closed
    275         * @since Commons IO 2.0
    276         */
    277        public static void closeQuietly(Closeable closeable) {
    278            try {
    279                if (closeable != null) {
    280                    closeable.close();
    281                }
    282            } catch (IOException ioe) {
    283                // ignore
    284            }
    285        }
    286
    287        /**
    288         * Unconditionally close a <code>Socket</code>.
    289         * <p>
    290         * Equivalent to {@link Socket#close()}, except any exceptions will be ignored.
    291         * This is typically used in finally blocks.
    292         * <p>
    293         * Example code:
    294         * <pre>
    295         *   Socket socket = null;
    296         *   try {
    297         *       socket = new Socket("http://www.foo.com/", 80);
    298         *       // process socket
    299         *       socket.close();
    300         *   } catch (Exception e) {
    301         *       // error handling
    302         *   } finally {
    303         *       IOUtils.closeQuietly(socket);
    304         *   }
    305         * </pre>
    306         *
    307         * @param sock the Socket to close, may be null or already closed
    308         * @since Commons IO 2.0
    309         */
    310        public static void closeQuietly(Socket sock){
    311            if (sock != null){
    312                try {
    313                    sock.close();
    314                } catch (IOException ioe) {
    315                    // ignored
    316                }
    317            }
    318        }
    319
    320        /**
    321         * Fetches entire contents of an <code>InputStream</code> and represent
    322         * same data as result InputStream.
    323         * <p>
    324         * This method is useful where,
    325         * <ul>
    326         * <li>Source InputStream is slow.</li>
    327         * <li>It has network resources associated, so we cannot keep it open for
    328         * long time.</li>
    329         * <li>It has network timeout associated.</li>
    330         * </ul>
    331         * It can be used in favor of {@link #toByteArray(InputStream)}, since it
    332         * avoids unnecessary allocation and copy of byte[].<br>
    333         * This method buffers the input internally, so there is no need to use a
    334         * <code>BufferedInputStream</code>.
    335         *
    336         * @param input Stream to be fully buffered.
    337         * @return A fully buffered stream.
    338         * @throws IOException if an I/O error occurs
    339         * @since Commons IO 2.0
    340         */
    341        public static InputStream toBufferedInputStream(InputStream input) throws IOException {
    342            return ByteArrayOutputStream.toBufferedInputStream(input);
    343        }
    344
    345        // read toByteArray
    346        //-----------------------------------------------------------------------
    347        /**
    348         * Get the contents of an <code>InputStream</code> as a <code>byte[]</code>.
    349         * <p>
    350         * This method buffers the input internally, so there is no need to use a
    351         * <code>BufferedInputStream</code>.
    352         *
    353         * @param input  the <code>InputStream</code> to read from
    354         * @return the requested byte array
    355         * @throws NullPointerException if the input is null
    356         * @throws IOException if an I/O error occurs
    357         */
    358        public static byte[] toByteArray(InputStream input) throws IOException {
    359            ByteArrayOutputStream output = new ByteArrayOutputStream();
    360            copy(input, output);
    361            return output.toByteArray();
    362        }
    363
    364        /**
    365         * Get the contents of a <code>Reader</code> as a <code>byte[]</code>
    366         * using the default character encoding of the platform.
    367         * <p>
    368         * This method buffers the input internally, so there is no need to use a
    369         * <code>BufferedReader</code>.
    370         *
    371         * @param input  the <code>Reader</code> to read from
    372         * @return the requested byte array
    373         * @throws NullPointerException if the input is null
    374         * @throws IOException if an I/O error occurs
    375         */
    376        public static byte[] toByteArray(Reader input) throws IOException {
    377            ByteArrayOutputStream output = new ByteArrayOutputStream();
    378            copy(input, output);
    379            return output.toByteArray();
    380        }
    381
    382        /**
    383         * Get the contents of a <code>Reader</code> as a <code>byte[]</code>
    384         * using the specified character encoding.
    385         * <p>
    386         * Character encoding names can be found at
    387         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    388         * <p>
    389         * This method buffers the input internally, so there is no need to use a
    390         * <code>BufferedReader</code>.
    391         *
    392         * @param input  the <code>Reader</code> to read from
    393         * @param encoding  the encoding to use, null means platform default
    394         * @return the requested byte array
    395         * @throws NullPointerException if the input is null
    396         * @throws IOException if an I/O error occurs
    397         * @since Commons IO 1.1
    398         */
    399        public static byte[] toByteArray(Reader input, String encoding)
    400                throws IOException {
    401            ByteArrayOutputStream output = new ByteArrayOutputStream();
    402            copy(input, output, encoding);
    403            return output.toByteArray();
    404        }
    405
    406        /**
    407         * Get the contents of a <code>String</code> as a <code>byte[]</code>
    408         * using the default character encoding of the platform.
    409         * <p>
    410         * This is the same as {@link String#getBytes()}.
    411         *
    412         * @param input  the <code>String</code> to convert
    413         * @return the requested byte array
    414         * @throws NullPointerException if the input is null
    415         * @throws IOException if an I/O error occurs (never occurs)
    416         * @deprecated Use {@link String#getBytes()}
    417         */
    418        @Deprecated
    419        public static byte[] toByteArray(String input) throws IOException {
    420            return input.getBytes();
    421        }
    422
    423        // read char[]
    424        //-----------------------------------------------------------------------
    425        /**
    426         * Get the contents of an <code>InputStream</code> as a character array
    427         * using the default character encoding of the platform.
    428         * <p>
    429         * This method buffers the input internally, so there is no need to use a
    430         * <code>BufferedInputStream</code>.
    431         *
    432         * @param is  the <code>InputStream</code> to read from
    433         * @return the requested character array
    434         * @throws NullPointerException if the input is null
    435         * @throws IOException if an I/O error occurs
    436         * @since Commons IO 1.1
    437         */
    438        public static char[] toCharArray(InputStream is) throws IOException {
    439            CharArrayWriter output = new CharArrayWriter();
    440            copy(is, output);
    441            return output.toCharArray();
    442        }
    443
    444        /**
    445         * Get the contents of an <code>InputStream</code> as a character array
    446         * using the specified character encoding.
    447         * <p>
    448         * Character encoding names can be found at
    449         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    450         * <p>
    451         * This method buffers the input internally, so there is no need to use a
    452         * <code>BufferedInputStream</code>.
    453         *
    454         * @param is  the <code>InputStream</code> to read from
    455         * @param encoding  the encoding to use, null means platform default
    456         * @return the requested character array
    457         * @throws NullPointerException if the input is null
    458         * @throws IOException if an I/O error occurs
    459         * @since Commons IO 1.1
    460         */
    461        public static char[] toCharArray(InputStream is, String encoding)
    462                throws IOException {
    463            CharArrayWriter output = new CharArrayWriter();
    464            copy(is, output, encoding);
    465            return output.toCharArray();
    466        }
    467
    468        /**
    469         * Get the contents of a <code>Reader</code> as a character array.
    470         * <p>
    471         * This method buffers the input internally, so there is no need to use a
    472         * <code>BufferedReader</code>.
    473         *
    474         * @param input  the <code>Reader</code> to read from
    475         * @return the requested character array
    476         * @throws NullPointerException if the input is null
    477         * @throws IOException if an I/O error occurs
    478         * @since Commons IO 1.1
    479         */
    480        public static char[] toCharArray(Reader input) throws IOException {
    481            CharArrayWriter sw = new CharArrayWriter();
    482            copy(input, sw);
    483            return sw.toCharArray();
    484        }
    485
    486        // read toString
    487        //-----------------------------------------------------------------------
    488        /**
    489         * Get the contents of an <code>InputStream</code> as a String
    490         * using the default character encoding of the platform.
    491         * <p>
    492         * This method buffers the input internally, so there is no need to use a
    493         * <code>BufferedInputStream</code>.
    494         *
    495         * @param input  the <code>InputStream</code> to read from
    496         * @return the requested String
    497         * @throws NullPointerException if the input is null
    498         * @throws IOException if an I/O error occurs
    499         */
    500        public static String toString(InputStream input) throws IOException {
    501            StringBuilderWriter sw = new StringBuilderWriter();
    502            copy(input, sw);
    503            return sw.toString();
    504        }
    505
    506        /**
    507         * Get the contents of an <code>InputStream</code> as a String
    508         * using the specified character encoding.
    509         * <p>
    510         * Character encoding names can be found at
    511         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    512         * <p>
    513         * This method buffers the input internally, so there is no need to use a
    514         * <code>BufferedInputStream</code>.
    515         *
    516         * @param input  the <code>InputStream</code> to read from
    517         * @param encoding  the encoding to use, null means platform default
    518         * @return the requested String
    519         * @throws NullPointerException if the input is null
    520         * @throws IOException if an I/O error occurs
    521         */
    522        public static String toString(InputStream input, String encoding)
    523                throws IOException {
    524            StringBuilderWriter sw = new StringBuilderWriter();
    525            copy(input, sw, encoding);
    526            return sw.toString();
    527        }
    528
    529        /**
    530         * Get the contents of a <code>Reader</code> as a String.
    531         * <p>
    532         * This method buffers the input internally, so there is no need to use a
    533         * <code>BufferedReader</code>.
    534         *
    535         * @param input  the <code>Reader</code> to read from
    536         * @return the requested String
    537         * @throws NullPointerException if the input is null
    538         * @throws IOException if an I/O error occurs
    539         */
    540        public static String toString(Reader input) throws IOException {
    541            StringBuilderWriter sw = new StringBuilderWriter();
    542            copy(input, sw);
    543            return sw.toString();
    544        }
    545
    546        /**
    547         * Get the contents of a <code>byte[]</code> as a String
    548         * using the default character encoding of the platform.
    549         *
    550         * @param input the byte array to read from
    551         * @return the requested String
    552         * @throws NullPointerException if the input is null
    553         * @throws IOException if an I/O error occurs (never occurs)
    554         * @deprecated Use {@link String#String(byte[])}
    555         */
    556        @Deprecated
    557        public static String toString(byte[] input) throws IOException {
    558            return new String(input);
    559        }
    560
    561        /**
    562         * Get the contents of a <code>byte[]</code> as a String
    563         * using the specified character encoding.
    564         * <p>
    565         * Character encoding names can be found at
    566         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    567         *
    568         * @param input the byte array to read from
    569         * @param encoding  the encoding to use, null means platform default
    570         * @return the requested String
    571         * @throws NullPointerException if the input is null
    572         * @throws IOException if an I/O error occurs (never occurs)
    573         * @deprecated Use {@link String#String(byte[],String)}
    574         */
    575        @Deprecated
    576        public static String toString(byte[] input, String encoding)
    577                throws IOException {
    578            if (encoding == null) {
    579                return new String(input);
    580            } else {
    581                return new String(input, encoding);
    582            }
    583        }
    584
    585        // readLines
    586        //-----------------------------------------------------------------------
    587        /**
    588         * Get the contents of an <code>InputStream</code> as a list of Strings,
    589         * one entry per line, using the default character encoding of the platform.
    590         * <p>
    591         * This method buffers the input internally, so there is no need to use a
    592         * <code>BufferedInputStream</code>.
    593         *
    594         * @param input  the <code>InputStream</code> to read from, not null
    595         * @return the list of Strings, never null
    596         * @throws NullPointerException if the input is null
    597         * @throws IOException if an I/O error occurs
    598         * @since Commons IO 1.1
    599         */
    600        public static List<String> readLines(InputStream input) throws IOException {
    601            InputStreamReader reader = new InputStreamReader(input);
    602            return readLines(reader);
    603        }
    604
    605        /**
    606         * Get the contents of an <code>InputStream</code> as a list of Strings,
    607         * one entry per line, using the specified character encoding.
    608         * <p>
    609         * Character encoding names can be found at
    610         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    611         * <p>
    612         * This method buffers the input internally, so there is no need to use a
    613         * <code>BufferedInputStream</code>.
    614         *
    615         * @param input  the <code>InputStream</code> to read from, not null
    616         * @param encoding  the encoding to use, null means platform default
    617         * @return the list of Strings, never null
    618         * @throws NullPointerException if the input is null
    619         * @throws IOException if an I/O error occurs
    620         * @since Commons IO 1.1
    621         */
    622        public static List<String> readLines(InputStream input, String encoding) throws IOException {
    623            if (encoding == null) {
    624                return readLines(input);
    625            } else {
    626                InputStreamReader reader = new InputStreamReader(input, encoding);
    627                return readLines(reader);
    628            }
    629        }
    630
    631        /**
    632         * Get the contents of a <code>Reader</code> as a list of Strings,
    633         * one entry per line.
    634         * <p>
    635         * This method buffers the input internally, so there is no need to use a
    636         * <code>BufferedReader</code>.
    637         *
    638         * @param input  the <code>Reader</code> to read from, not null
    639         * @return the list of Strings, never null
    640         * @throws NullPointerException if the input is null
    641         * @throws IOException if an I/O error occurs
    642         * @since Commons IO 1.1
    643         */
    644        public static List<String> readLines(Reader input) throws IOException {
    645            BufferedReader reader = new BufferedReader(input);
    646            List<String> list = new ArrayList<String>();
    647            String line = reader.readLine();
    648            while (line != null) {
    649                list.add(line);
    650                line = reader.readLine();
    651            }
    652            return list;
    653        }
    654
    655        // lineIterator
    656        //-----------------------------------------------------------------------
    657        /**
    658         * Return an Iterator for the lines in a <code>Reader</code>.
    659         * <p>
    660         * <code>LineIterator</code> holds a reference to the open
    661         * <code>Reader</code> specified here. When you have finished with the
    662         * iterator you should close the reader to free internal resources.
    663         * This can be done by closing the reader directly, or by calling
    664         * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
    665         * <p>
    666         * The recommended usage pattern is:
    667         * <pre>
    668         * try {
    669         *   LineIterator it = IOUtils.lineIterator(reader);
    670         *   while (it.hasNext()) {
    671         *     String line = it.nextLine();
    672         *     /// do something with line
    673         *   }
    674         * } finally {
    675         *   IOUtils.closeQuietly(reader);
    676         * }
    677         * </pre>
    678         *
    679         * @param reader  the <code>Reader</code> to read from, not null
    680         * @return an Iterator of the lines in the reader, never null
    681         * @throws IllegalArgumentException if the reader is null
    682         * @since Commons IO 1.2
    683         */
    684        public static LineIterator lineIterator(Reader reader) {
    685            return new LineIterator(reader);
    686        }
    687
    688        /**
    689         * Return an Iterator for the lines in an <code>InputStream</code>, using
    690         * the character encoding specified (or default encoding if null).
    691         * <p>
    692         * <code>LineIterator</code> holds a reference to the open
    693         * <code>InputStream</code> specified here. When you have finished with
    694         * the iterator you should close the stream to free internal resources.
    695         * This can be done by closing the stream directly, or by calling
    696         * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
    697         * <p>
    698         * The recommended usage pattern is:
    699         * <pre>
    700         * try {
    701         *   LineIterator it = IOUtils.lineIterator(stream, "UTF-8");
    702         *   while (it.hasNext()) {
    703         *     String line = it.nextLine();
    704         *     /// do something with line
    705         *   }
    706         * } finally {
    707         *   IOUtils.closeQuietly(stream);
    708         * }
    709         * </pre>
    710         *
    711         * @param input  the <code>InputStream</code> to read from, not null
    712         * @param encoding  the encoding to use, null means platform default
    713         * @return an Iterator of the lines in the reader, never null
    714         * @throws IllegalArgumentException if the input is null
    715         * @throws IOException if an I/O error occurs, such as if the encoding is invalid
    716         * @since Commons IO 1.2
    717         */
    718        public static LineIterator lineIterator(InputStream input, String encoding)
    719                         throws IOException {
    720            Reader reader = null;
    721            if (encoding == null) {
    722                reader = new InputStreamReader(input);
    723            } else {
    724                reader = new InputStreamReader(input, encoding);
    725            }
    726            return new LineIterator(reader);
    727        }
    728
    729        //-----------------------------------------------------------------------
    730        /**
    731         * Convert the specified CharSequence to an input stream, encoded as bytes
    732         * using the default character encoding of the platform.
    733         *
    734         * @param input the CharSequence to convert
    735         * @return an input stream
    736         * @since Commons IO 2.0
    737         */
    738        public static InputStream toInputStream(CharSequence input) {
    739            return toInputStream(input.toString());
    740        }
    741
    742        /**
    743         * Convert the specified CharSequence to an input stream, encoded as bytes
    744         * using the specified character encoding.
    745         * <p>
    746         * Character encoding names can be found at
    747         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    748         *
    749         * @param input the CharSequence to convert
    750         * @param encoding the encoding to use, null means platform default
    751         * @throws IOException if the encoding is invalid
    752         * @return an input stream
    753         * @since Commons IO 2.0
    754         */
    755        public static InputStream toInputStream(CharSequence input, String encoding) throws IOException {
    756            return toInputStream(input.toString(), encoding);
    757        }
    758
    759        //-----------------------------------------------------------------------
    760        /**
    761         * Convert the specified string to an input stream, encoded as bytes
    762         * using the default character encoding of the platform.
    763         *
    764         * @param input the string to convert
    765         * @return an input stream
    766         * @since Commons IO 1.1
    767         */
    768        public static InputStream toInputStream(String input) {
    769            byte[] bytes = input.getBytes();
    770            return new ByteArrayInputStream(bytes);
    771        }
    772
    773        /**
    774         * Convert the specified string to an input stream, encoded as bytes
    775         * using the specified character encoding.
    776         * <p>
    777         * Character encoding names can be found at
    778         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    779         *
    780         * @param input the string to convert
    781         * @param encoding the encoding to use, null means platform default
    782         * @throws IOException if the encoding is invalid
    783         * @return an input stream
    784         * @since Commons IO 1.1
    785         */
    786        public static InputStream toInputStream(String input, String encoding) throws IOException {
    787            byte[] bytes = encoding != null ? input.getBytes(encoding) : input.getBytes();
    788            return new ByteArrayInputStream(bytes);
    789        }
    790
    791        // write byte[]
    792        //-----------------------------------------------------------------------
    793        /**
    794         * Writes bytes from a <code>byte[]</code> to an <code>OutputStream</code>.
    795         *
    796         * @param data  the byte array to write, do not modify during output,
    797         * null ignored
    798         * @param output  the <code>OutputStream</code> to write to
    799         * @throws NullPointerException if output is null
    800         * @throws IOException if an I/O error occurs
    801         * @since Commons IO 1.1
    802         */
    803        public static void write(byte[] data, OutputStream output)
    804                throws IOException {
    805            if (data != null) {
    806                output.write(data);
    807            }
    808        }
    809
    810        /**
    811         * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code>
    812         * using the default character encoding of the platform.
    813         * <p>
    814         * This method uses {@link String#String(byte[])}.
    815         *
    816         * @param data  the byte array to write, do not modify during output,
    817         * null ignored
    818         * @param output  the <code>Writer</code> to write to
    819         * @throws NullPointerException if output is null
    820         * @throws IOException if an I/O error occurs
    821         * @since Commons IO 1.1
    822         */
    823        public static void write(byte[] data, Writer output) throws IOException {
    824            if (data != null) {
    825                output.write(new String(data));
    826            }
    827        }
    828
    829        /**
    830         * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code>
    831         * using the specified character encoding.
    832         * <p>
    833         * Character encoding names can be found at
    834         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    835         * <p>
    836         * This method uses {@link String#String(byte[], String)}.
    837         *
    838         * @param data  the byte array to write, do not modify during output,
    839         * null ignored
    840         * @param output  the <code>Writer</code> to write to
    841         * @param encoding  the encoding to use, null means platform default
    842         * @throws NullPointerException if output is null
    843         * @throws IOException if an I/O error occurs
    844         * @since Commons IO 1.1
    845         */
    846        public static void write(byte[] data, Writer output, String encoding)
    847                throws IOException {
    848            if (data != null) {
    849                if (encoding == null) {
    850                    write(data, output);
    851                } else {
    852                    output.write(new String(data, encoding));
    853                }
    854            }
    855        }
    856
    857        // write char[]
    858        //-----------------------------------------------------------------------
    859        /**
    860         * Writes chars from a <code>char[]</code> to a <code>Writer</code>
    861         * using the default character encoding of the platform.
    862         *
    863         * @param data  the char array to write, do not modify during output,
    864         * null ignored
    865         * @param output  the <code>Writer</code> to write to
    866         * @throws NullPointerException if output is null
    867         * @throws IOException if an I/O error occurs
    868         * @since Commons IO 1.1
    869         */
    870        public static void write(char[] data, Writer output) throws IOException {
    871            if (data != null) {
    872                output.write(data);
    873            }
    874        }
    875
    876        /**
    877         * Writes chars from a <code>char[]</code> to bytes on an
    878         * <code>OutputStream</code>.
    879         * <p>
    880         * This method uses {@link String#String(char[])} and
    881         * {@link String#getBytes()}.
    882         *
    883         * @param data  the char array to write, do not modify during output,
    884         * null ignored
    885         * @param output  the <code>OutputStream</code> to write to
    886         * @throws NullPointerException if output is null
    887         * @throws IOException if an I/O error occurs
    888         * @since Commons IO 1.1
    889         */
    890        public static void write(char[] data, OutputStream output)
    891                throws IOException {
    892            if (data != null) {
    893                output.write(new String(data).getBytes());
    894            }
    895        }
    896
    897        /**
    898         * Writes chars from a <code>char[]</code> to bytes on an
    899         * <code>OutputStream</code> using the specified character encoding.
    900         * <p>
    901         * Character encoding names can be found at
    902         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    903         * <p>
    904         * This method uses {@link String#String(char[])} and
    905         * {@link String#getBytes(String)}.
    906         *
    907         * @param data  the char array to write, do not modify during output,
    908         * null ignored
    909         * @param output  the <code>OutputStream</code> to write to
    910         * @param encoding  the encoding to use, null means platform default
    911         * @throws NullPointerException if output is null
    912         * @throws IOException if an I/O error occurs
    913         * @since Commons IO 1.1
    914         */
    915        public static void write(char[] data, OutputStream output, String encoding)
    916                throws IOException {
    917            if (data != null) {
    918                if (encoding == null) {
    919                    write(data, output);
    920                } else {
    921                    output.write(new String(data).getBytes(encoding));
    922                }
    923            }
    924        }
    925
    926        // write CharSequence
    927        //-----------------------------------------------------------------------
    928        /**
    929         * Writes chars from a <code>CharSequence</code> to a <code>Writer</code>.
    930         *
    931         * @param data  the <code>CharSequence</code> to write, null ignored
    932         * @param output  the <code>Writer</code> to write to
    933         * @throws NullPointerException if output is null
    934         * @throws IOException if an I/O error occurs
    935         * @since Commons IO 2.0
    936         */
    937        public static void write(CharSequence data, Writer output) throws IOException {
    938            if (data != null) {
    939                write(data.toString(), output);
    940            }
    941        }
    942
    943        /**
    944         * Writes chars from a <code>CharSequence</code> to bytes on an
    945         * <code>OutputStream</code> using the default character encoding of the
    946         * platform.
    947         * <p>
    948         * This method uses {@link String#getBytes()}.
    949         *
    950         * @param data  the <code>CharSequence</code> to write, null ignored
    951         * @param output  the <code>OutputStream</code> to write to
    952         * @throws NullPointerException if output is null
    953         * @throws IOException if an I/O error occurs
    954         * @since Commons IO 2.0
    955         */
    956        public static void write(CharSequence data, OutputStream output)
    957                throws IOException {
    958            if (data != null) {
    959                write(data.toString(), output);
    960            }
    961        }
    962
    963        /**
    964         * Writes chars from a <code>CharSequence</code> to bytes on an
    965         * <code>OutputStream</code> using the specified character encoding.
    966         * <p>
    967         * Character encoding names can be found at
    968         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    969         * <p>
    970         * This method uses {@link String#getBytes(String)}.
    971         *
    972         * @param data  the <code>CharSequence</code> to write, null ignored
    973         * @param output  the <code>OutputStream</code> to write to
    974         * @param encoding  the encoding to use, null means platform default
    975         * @throws NullPointerException if output is null
    976         * @throws IOException if an I/O error occurs
    977         * @since Commons IO 2.0
    978         */
    979        public static void write(CharSequence data, OutputStream output, String encoding)
    980                throws IOException {
    981            if (data != null) {
    982                write(data.toString(), output, encoding);
    983            }
    984        }
    985
    986        // write String
    987        //-----------------------------------------------------------------------
    988        /**
    989         * Writes chars from a <code>String</code> to a <code>Writer</code>.
    990         *
    991         * @param data  the <code>String</code> to write, null ignored
    992         * @param output  the <code>Writer</code> to write to
    993         * @throws NullPointerException if output is null
    994         * @throws IOException if an I/O error occurs
    995         * @since Commons IO 1.1
    996         */
    997        public static void write(String data, Writer output) throws IOException {
    998            if (data != null) {
    999                output.write(data);
    1000            }
    1001        }
    1002
    1003        /**
    1004         * Writes chars from a <code>String</code> to bytes on an
    1005         * <code>OutputStream</code> using the default character encoding of the
    1006         * platform.
    1007         * <p>
    1008         * This method uses {@link String#getBytes()}.
    1009         *
    1010         * @param data  the <code>String</code> to write, null ignored
    1011         * @param output  the <code>OutputStream</code> to write to
    1012         * @throws NullPointerException if output is null
    1013         * @throws IOException if an I/O error occurs
    1014         * @since Commons IO 1.1
    1015         */
    1016        public static void write(String data, OutputStream output)
    1017                throws IOException {
    1018            if (data != null) {
    1019                output.write(data.getBytes());
    1020            }
    1021        }
    1022
    1023        /**
    1024         * Writes chars from a <code>String</code> to bytes on an
    1025         * <code>OutputStream</code> using the specified character encoding.
    1026         * <p>
    1027         * Character encoding names can be found at
    1028         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    1029         * <p>
    1030         * This method uses {@link String#getBytes(String)}.
    1031         *
    1032         * @param data  the <code>String</code> to write, null ignored
    1033         * @param output  the <code>OutputStream</code> to write to
    1034         * @param encoding  the encoding to use, null means platform default
    1035         * @throws NullPointerException if output is null
    1036         * @throws IOException if an I/O error occurs
    1037         * @since Commons IO 1.1
    1038         */
    1039        public static void write(String data, OutputStream output, String encoding)
    1040                throws IOException {
    1041            if (data != null) {
    1042                if (encoding == null) {
    1043                    write(data, output);
    1044                } else {
    1045                    output.write(data.getBytes(encoding));
    1046                }
    1047            }
    1048        }
    1049
    1050        // write StringBuffer
    1051        //-----------------------------------------------------------------------
    1052        /**
    1053         * Writes chars from a <code>StringBuffer</code> to a <code>Writer</code>.
    1054         *
    1055         * @param data  the <code>StringBuffer</code> to write, null ignored
    1056         * @param output  the <code>Writer</code> to write to
    1057         * @throws NullPointerException if output is null
    1058         * @throws IOException if an I/O error occurs
    1059         * @since Commons IO 1.1
    1060         * @deprecated replaced by write(CharSequence, Writer)
    1061         */
    1062        @Deprecated
    1063        public static void write(StringBuffer data, Writer output)
    1064                throws IOException {
    1065            if (data != null) {
    1066                output.write(data.toString());
    1067            }
    1068        }
    1069
    1070        /**
    1071         * Writes chars from a <code>StringBuffer</code> to bytes on an
    1072         * <code>OutputStream</code> using the default character encoding of the
    1073         * platform.
    1074         * <p>
    1075         * This method uses {@link String#getBytes()}.
    1076         *
    1077         * @param data  the <code>StringBuffer</code> to write, null ignored
    1078         * @param output  the <code>OutputStream</code> to write to
    1079         * @throws NullPointerException if output is null
    1080         * @throws IOException if an I/O error occurs
    1081         * @since Commons IO 1.1
    1082         * @deprecated replaced by write(CharSequence, OutputStream)
    1083         */
    1084        @Deprecated
    1085        public static void write(StringBuffer data, OutputStream output)
    1086                throws IOException {
    1087            if (data != null) {
    1088                output.write(data.toString().getBytes());
    1089            }
    1090        }
    1091
    1092        /**
    1093         * Writes chars from a <code>StringBuffer</code> to bytes on an
    1094         * <code>OutputStream</code> using the specified character encoding.
    1095         * <p>
    1096         * Character encoding names can be found at
    1097         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    1098         * <p>
    1099         * This method uses {@link String#getBytes(String)}.
    1100         *
    1101         * @param data  the <code>StringBuffer</code> to write, null ignored
    1102         * @param output  the <code>OutputStream</code> to write to
    1103         * @param encoding  the encoding to use, null means platform default
    1104         * @throws NullPointerException if output is null
    1105         * @throws IOException if an I/O error occurs
    1106         * @since Commons IO 1.1
    1107         * @deprecated replaced by write(CharSequence, OutputStream, String)
    1108         */
    1109        @Deprecated
    1110        public static void write(StringBuffer data, OutputStream output,
    1111                String encoding) throws IOException {
    1112            if (data != null) {
    1113                if (encoding == null) {
    1114                    write(data, output);
    1115                } else {
    1116                    output.write(data.toString().getBytes(encoding));
    1117                }
    1118            }
    1119        }
    1120
    1121        // writeLines
    1122        //-----------------------------------------------------------------------
    1123        /**
    1124         * Writes the <code>toString()</code> value of each item in a collection to
    1125         * an <code>OutputStream</code> line by line, using the default character
    1126         * encoding of the platform and the specified line ending.
    1127         *
    1128         * @param lines  the lines to write, null entries produce blank lines
    1129         * @param lineEnding  the line separator to use, null is system default
    1130         * @param output  the <code>OutputStream</code> to write to, not null, not closed
    1131         * @throws NullPointerException if the output is null
    1132         * @throws IOException if an I/O error occurs
    1133         * @since Commons IO 1.1
    1134         */
    1135        public static void writeLines(Collection<?> lines, String lineEnding,
    1136                OutputStream output) throws IOException {
    1137            if (lines == null) {
    1138                return;
    1139            }
    1140            if (lineEnding == null) {
    1141                lineEnding = LINE_SEPARATOR;
    1142            }
    1143            for (Object line : lines) {
    1144                if (line != null) {
    1145                    output.write(line.toString().getBytes());
    1146                }
    1147                output.write(lineEnding.getBytes());
    1148            }
    1149        }
    1150
    1151        /**
    1152         * Writes the <code>toString()</code> value of each item in a collection to
    1153         * an <code>OutputStream</code> line by line, using the specified character
    1154         * encoding and the specified line ending.
    1155         * <p>
    1156         * Character encoding names can be found at
    1157         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    1158         *
    1159         * @param lines  the lines to write, null entries produce blank lines
    1160         * @param lineEnding  the line separator to use, null is system default
    1161         * @param output  the <code>OutputStream</code> to write to, not null, not closed
    1162         * @param encoding  the encoding to use, null means platform default
    1163         * @throws NullPointerException if the output is null
    1164         * @throws IOException if an I/O error occurs
    1165         * @since Commons IO 1.1
    1166         */
    1167        public static void writeLines(Collection<?> lines, String lineEnding,
    1168                OutputStream output, String encoding) throws IOException {
    1169            if (encoding == null) {
    1170                writeLines(lines, lineEnding, output);
    1171            } else {
    1172                if (lines == null) {
    1173                    return;
    1174                }
    1175                if (lineEnding == null) {
    1176                    lineEnding = LINE_SEPARATOR;
    1177                }
    1178                for (Object line : lines) {
    1179                    if (line != null) {
    1180                        output.write(line.toString().getBytes(encoding));
    1181                    }
    1182                    output.write(lineEnding.getBytes(encoding));
    1183                }
    1184            }
    1185        }
    1186
    1187        /**
    1188         * Writes the <code>toString()</code> value of each item in a collection to
    1189         * a <code>Writer</code> line by line, using the specified line ending.
    1190         *
    1191         * @param lines  the lines to write, null entries produce blank lines
    1192         * @param lineEnding  the line separator to use, null is system default
    1193         * @param writer  the <code>Writer</code> to write to, not null, not closed
    1194         * @throws NullPointerException if the input is null
    1195         * @throws IOException if an I/O error occurs
    1196         * @since Commons IO 1.1
    1197         */
    1198        public static void writeLines(Collection<?> lines, String lineEnding,
    1199                Writer writer) throws IOException {
    1200            if (lines == null) {
    1201                return;
    1202            }
    1203            if (lineEnding == null) {
    1204                lineEnding = LINE_SEPARATOR;
    1205            }
    1206            for (Object line : lines) {
    1207                if (line != null) {
    1208                    writer.write(line.toString());
    1209                }
    1210                writer.write(lineEnding);
    1211            }
    1212        }
    1213
    1214        // copy from InputStream
    1215        //-----------------------------------------------------------------------
    1216        /**
    1217         * Copy bytes from an <code>InputStream</code> to an
    1218         * <code>OutputStream</code>.
    1219         * <p>
    1220         * This method buffers the input internally, so there is no need to use a
    1221         * <code>BufferedInputStream</code>.
    1222         * <p>
    1223         * Large streams (over 2GB) will return a bytes copied value of
    1224         * <code>-1</code> after the copy has completed since the correct
    1225         * number of bytes cannot be returned as an int. For large streams
    1226         * use the <code>copyLarge(InputStream, OutputStream)</code> method.
    1227         *
    1228         * @param input  the <code>InputStream</code> to read from
    1229         * @param output  the <code>OutputStream</code> to write to
    1230         * @return the number of bytes copied, or -1 if &gt; Integer.MAX_VALUE
    1231         * @throws NullPointerException if the input or output is null
    1232         * @throws IOException if an I/O error occurs
    1233         * @since Commons IO 1.1
    1234         */
    1235        public static int copy(InputStream input, OutputStream output) throws IOException {
    1236            long count = copyLarge(input, output);
    1237            if (count > Integer.MAX_VALUE) {
    1238                return -1;
    1239            }
    1240            return (int) count;
    1241        }
    1242
    1243        /**
    1244         * Copy bytes from a large (over 2GB) <code>InputStream</code> to an
    1245         * <code>OutputStream</code>.
    1246         * <p>
    1247         * This method buffers the input internally, so there is no need to use a
    1248         * <code>BufferedInputStream</code>.
    1249         *
    1250         * @param input  the <code>InputStream</code> to read from
    1251         * @param output  the <code>OutputStream</code> to write to
    1252         * @return the number of bytes copied
    1253         * @throws NullPointerException if the input or output is null
    1254         * @throws IOException if an I/O error occurs
    1255         * @since Commons IO 1.3
    1256         */
    1257        public static long copyLarge(InputStream input, OutputStream output)
    1258                throws IOException {
    1259            byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
    1260            long count = 0;
    1261            int n = 0;
    1262            while (-1 != (n = input.read(buffer))) {
    1263                output.write(buffer, 0, n);
    1264                count += n;
    1265            }
    1266            return count;
    1267        }
    1268
    1269        /**
    1270         * Copy bytes from an <code>InputStream</code> to chars on a
    1271         * <code>Writer</code> using the default character encoding of the platform.
    1272         * <p>
    1273         * This method buffers the input internally, so there is no need to use a
    1274         * <code>BufferedInputStream</code>.
    1275         * <p>
    1276         * This method uses {@link InputStreamReader}.
    1277         *
    1278         * @param input  the <code>InputStream</code> to read from
    1279         * @param output  the <code>Writer</code> to write to
    1280         * @throws NullPointerException if the input or output is null
    1281         * @throws IOException if an I/O error occurs
    1282         * @since Commons IO 1.1
    1283         */
    1284        public static void copy(InputStream input, Writer output)
    1285                throws IOException {
    1286            InputStreamReader in = new InputStreamReader(input);
    1287            copy(in, output);
    1288        }
    1289
    1290        /**
    1291         * Copy bytes from an <code>InputStream</code> to chars on a
    1292         * <code>Writer</code> using the specified character encoding.
    1293         * <p>
    1294         * This method buffers the input internally, so there is no need to use a
    1295         * <code>BufferedInputStream</code>.
    1296         * <p>
    1297         * Character encoding names can be found at
    1298         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    1299         * <p>
    1300         * This method uses {@link InputStreamReader}.
    1301         *
    1302         * @param input  the <code>InputStream</code> to read from
    1303         * @param output  the <code>Writer</code> to write to
    1304         * @param encoding  the encoding to use, null means platform default
    1305         * @throws NullPointerException if the input or output is null
    1306         * @throws IOException if an I/O error occurs
    1307         * @since Commons IO 1.1
    1308         */
    1309        public static void copy(InputStream input, Writer output, String encoding)
    1310                throws IOException {
    1311            if (encoding == null) {
    1312                copy(input, output);
    1313            } else {
    1314                InputStreamReader in = new InputStreamReader(input, encoding);
    1315                copy(in, output);
    1316            }
    1317        }
    1318
    1319        // copy from Reader
    1320        //-----------------------------------------------------------------------
    1321        /**
    1322         * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
    1323         * <p>
    1324         * This method buffers the input internally, so there is no need to use a
    1325         * <code>BufferedReader</code>.
    1326         * <p>
    1327         * Large streams (over 2GB) will return a chars copied value of
    1328         * <code>-1</code> after the copy has completed since the correct
    1329         * number of chars cannot be returned as an int. For large streams
    1330         * use the <code>copyLarge(Reader, Writer)</code> method.
    1331         *
    1332         * @param input  the <code>Reader</code> to read from
    1333         * @param output  the <code>Writer</code> to write to
    1334         * @return the number of characters copied, or -1 if &gt; Integer.MAX_VALUE
    1335         * @throws NullPointerException if the input or output is null
    1336         * @throws IOException if an I/O error occurs
    1337         * @since Commons IO 1.1
    1338         */
    1339        public static int copy(Reader input, Writer output) throws IOException {
    1340            long count = copyLarge(input, output);
    1341            if (count > Integer.MAX_VALUE) {
    1342                return -1;
    1343            }
    1344            return (int) count;
    1345        }
    1346
    1347        /**
    1348         * Copy chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>.
    1349         * <p>
    1350         * This method buffers the input internally, so there is no need to use a
    1351         * <code>BufferedReader</code>.
    1352         *
    1353         * @param input  the <code>Reader</code> to read from
    1354         * @param output  the <code>Writer</code> to write to
    1355         * @return the number of characters copied
    1356         * @throws NullPointerException if the input or output is null
    1357         * @throws IOException if an I/O error occurs
    1358         * @since Commons IO 1.3
    1359         */
    1360        public static long copyLarge(Reader input, Writer output) throws IOException {
    1361            char[] buffer = new char[DEFAULT_BUFFER_SIZE];
    1362            long count = 0;
    1363            int n = 0;
    1364            while (-1 != (n = input.read(buffer))) {
    1365                output.write(buffer, 0, n);
    1366                count += n;
    1367            }
    1368            return count;
    1369        }
    1370
    1371        /**
    1372         * Copy chars from a <code>Reader</code> to bytes on an
    1373         * <code>OutputStream</code> using the default character encoding of the
    1374         * platform, and calling flush.
    1375         * <p>
    1376         * This method buffers the input internally, so there is no need to use a
    1377         * <code>BufferedReader</code>.
    1378         * <p>
    1379         * Due to the implementation of OutputStreamWriter, this method performs a
    1380         * flush.
    1381         * <p>
    1382         * This method uses {@link OutputStreamWriter}.
    1383         *
    1384         * @param input  the <code>Reader</code> to read from
    1385         * @param output  the <code>OutputStream</code> to write to
    1386         * @throws NullPointerException if the input or output is null
    1387         * @throws IOException if an I/O error occurs
    1388         * @since Commons IO 1.1
    1389         */
    1390        public static void copy(Reader input, OutputStream output)
    1391                throws IOException {
    1392            OutputStreamWriter out = new OutputStreamWriter(output);
    1393            copy(input, out);
    1394            // XXX Unless anyone is planning on rewriting OutputStreamWriter, we
    1395            // have to flush here.
    1396            out.flush();
    1397        }
    1398
    1399        /**
    1400         * Copy chars from a <code>Reader</code> to bytes on an
    1401         * <code>OutputStream</code> using the specified character encoding, and
    1402         * calling flush.
    1403         * <p>
    1404         * This method buffers the input internally, so there is no need to use a
    1405         * <code>BufferedReader</code>.
    1406         * <p>
    1407         * Character encoding names can be found at
    1408         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    1409         * <p>
    1410         * Due to the implementation of OutputStreamWriter, this method performs a
    1411         * flush.
    1412         * <p>
    1413         * This method uses {@link OutputStreamWriter}.
    1414         *
    1415         * @param input  the <code>Reader</code> to read from
    1416         * @param output  the <code>OutputStream</code> to write to
    1417         * @param encoding  the encoding to use, null means platform default
    1418         * @throws NullPointerException if the input or output is null
    1419         * @throws IOException if an I/O error occurs
    1420         * @since Commons IO 1.1
    1421         */
    1422        public static void copy(Reader input, OutputStream output, String encoding)
    1423                throws IOException {
    1424            if (encoding == null) {
    1425                copy(input, output);
    1426            } else {
    1427                OutputStreamWriter out = new OutputStreamWriter(output, encoding);
    1428                copy(input, out);
    1429                // XXX Unless anyone is planning on rewriting OutputStreamWriter,
    1430                // we have to flush here.
    1431                out.flush();
    1432            }
    1433        }
    1434
    1435        // content equals
    1436        //-----------------------------------------------------------------------
    1437        /**
    1438         * Compare the contents of two Streams to determine if they are equal or
    1439         * not.
    1440         * <p>
    1441         * This method buffers the input internally using
    1442         * <code>BufferedInputStream</code> if they are not already buffered.
    1443         *
    1444         * @param input1  the first stream
    1445         * @param input2  the second stream
    1446         * @return true if the content of the streams are equal or they both don't
    1447         * exist, false otherwise
    1448         * @throws NullPointerException if either input is null
    1449         * @throws IOException if an I/O error occurs
    1450         */
    1451        public static boolean contentEquals(InputStream input1, InputStream input2)
    1452                throws IOException {
    1453            if (!(input1 instanceof BufferedInputStream)) {
    1454                input1 = new BufferedInputStream(input1);
    1455            }
    1456            if (!(input2 instanceof BufferedInputStream)) {
    1457                input2 = new BufferedInputStream(input2);
    1458            }
    1459
    1460            int ch = input1.read();
    1461            while (-1 != ch) {
    1462                int ch2 = input2.read();
    1463                if (ch != ch2) {
    1464                    return false;
    1465                }
    1466                ch = input1.read();
    1467            }
    1468
    1469            int ch2 = input2.read();
    1470            return (ch2 == -1);
    1471        }
    1472
    1473        /**
    1474         * Compare the contents of two Readers to determine if they are equal or
    1475         * not.
    1476         * <p>
    1477         * This method buffers the input internally using
    1478         * <code>BufferedReader</code> if they are not already buffered.
    1479         *
    1480         * @param input1  the first reader
    1481         * @param input2  the second reader
    1482         * @return true if the content of the readers are equal or they both don't
    1483         * exist, false otherwise
    1484         * @throws NullPointerException if either input is null
    1485         * @throws IOException if an I/O error occurs
    1486         * @since Commons IO 1.1
    1487         */
    1488        public static boolean contentEquals(Reader input1, Reader input2)
    1489                throws IOException {
    1490            if (!(input1 instanceof BufferedReader)) {
    1491                input1 = new BufferedReader(input1);
    1492            }
    1493            if (!(input2 instanceof BufferedReader)) {
    1494                input2 = new BufferedReader(input2);
    1495            }
    1496
    1497            int ch = input1.read();
    1498            while (-1 != ch) {
    1499                int ch2 = input2.read();
    1500                if (ch != ch2) {
    1501                    return false;
    1502                }
    1503                ch = input1.read();
    1504            }
    1505
    1506            int ch2 = input2.read();
    1507            return (ch2 == -1);
    1508        }
    1509
    1510        /**
    1511         * Skip bytes from an input byte stream.
    1512         * This implementation guarantees that it will read as many bytes
    1513         * as possible before giving up; this may not always be the case for
    1514         * subclasses of {@link Reader}.
    1515         *
    1516         * @param input byte stream to skip
    1517         * @param toSkip number of bytes to skip.
    1518         * @return number of bytes actually skipped.
    1519         *
    1520         * @see InputStream#skip(long)
    1521         *
    1522         * @throws IOException if there is a problem reading the file
    1523         * @throws IllegalArgumentException if toSkip is negative
    1524         * @since Commons IO 2.0
    1525         */
    1526        public static long skip(InputStream input, long toSkip) throws IOException {
    1527            if (toSkip < 0) {
    1528                throw new IllegalArgumentException("Skip count must be non-negative, actual: "+toSkip);
    1529            }
    1530            /*
    1531             * N.B. no need to synchronize this because:
    1532             * - we don't care if the buffer is created multiple times (the data is ignored)
    1533             * - we always use the same size buffer, so if it it is recreated it will still be OK
    1534             * (if the buffer size were variable, we would need to synch. to ensure some other thread
    1535             * did not create a smaller one)
    1536             */
    1537            if (SKIP_BYTE_BUFFER == null){
    1538                SKIP_BYTE_BUFFER = new byte[SKIP_BUFFER_SIZE];
    1539            }
    1540            long remain=toSkip;
    1541            while(remain > 0) {
    1542                long n = input.read(SKIP_BYTE_BUFFER, 0, (int) Math.min(remain, SKIP_BUFFER_SIZE));
    1543                if (n < 0) { // EOF
    1544                    break;
    1545                }
    1546                remain -= n;
    1547            }
    1548            return toSkip - remain;
    1549        }
    1550
    1551        /**
    1552         * Skip characters from an input character stream.
    1553         * This implementation guarantees that it will read as many characters
    1554         * as possible before giving up; this may not always be the case for
    1555         * subclasses of {@link Reader}.
    1556         *
    1557         * @param input character stream to skip
    1558         * @param toSkip number of characters to skip.
    1559         * @return number of characters actually skipped.
    1560         *
    1561         * @see Reader#skip(long)
    1562         *
    1563         * @throws IOException if there is a problem reading the file
    1564         * @throws IllegalArgumentException if toSkip is negative
    1565         * @since Commons IO 2.0
    1566         */
    1567        public static long skip(Reader input, long toSkip) throws IOException {
    1568            if (toSkip < 0) {
    1569                throw new IllegalArgumentException("Skip count must be non-negative, actual: "+toSkip);
    1570            }
    1571            /*
    1572             * N.B. no need to synchronize this because:
    1573             * - we don't care if the buffer is created multiple times (the data is ignored)
    1574             * - we always use the same size buffer, so if it it is recreated it will still be OK
    1575             * (if the buffer size were variable, we would need to synch. to ensure some other thread
    1576             * did not create a smaller one)
    1577             */
    1578            if (SKIP_CHAR_BUFFER == null){
    1579                SKIP_CHAR_BUFFER = new char[SKIP_BUFFER_SIZE];
    1580            }
    1581            long remain=toSkip;
    1582            while(remain > 0) {
    1583                long n = input.read(SKIP_CHAR_BUFFER, 0, (int) Math.min(remain, SKIP_BUFFER_SIZE));
    1584                if (n < 0) { // EOF
    1585                    break;
    1586                }
    1587                remain -= n;
    1588            }
    1589            return toSkip - remain;
    1590        }
    1591
    1592        /**
    1593         * Skip the requested number of bytes or fail if there are not enough left.
    1594         * <p>
    1595         * This allows for the possibility that {@link InputStream#skip(long)} may
    1596         * not skip as many bytes as requested (most likely because of reaching EOF).
    1597         *
    1598         * @param input stream to skip
    1599         * @param toSkip the number of bytes to skip
    1600         * @see InputStream#skip(long)
    1601         *
    1602         * @throws IOException if there is a problem reading the file
    1603         * @throws IllegalArgumentException if toSkip is negative
    1604         * @throws EOFException if the number of bytes skipped was incorrect
    1605         * @since Commons IO 2.0
    1606         */
    1607        public static void skipFully(InputStream input, long toSkip) throws IOException {
    1608            if (toSkip < 0){
    1609                throw new IllegalArgumentException("Bytes to skip must not be negative: "+toSkip);
    1610            }
    1611            long skipped = skip(input, toSkip);
    1612            if (skipped != toSkip) {
    1613                throw new EOFException("Bytes to skip: "+toSkip+" actual: "+skipped);
    1614            }
    1615        }
    1616
    1617        /**
    1618         * Skip the requested number of characters or fail if there are not enough left.
    1619         * <p>
    1620         * This allows for the possibility that {@link Reader#skip(long)} may
    1621         * not skip as many characters as requested (most likely because of reaching EOF).
    1622         *
    1623         * @param input stream to skip
    1624         * @param toSkip the number of characters to skip
    1625         * @see Reader#skip(long)
    1626         *
    1627         * @throws IOException if there is a problem reading the file
    1628         * @throws IllegalArgumentException if toSkip is negative
    1629         * @throws EOFException if the number of characters skipped was incorrect
    1630         * @since Commons IO 2.0
    1631         */
    1632        public static void skipFully(Reader input, long toSkip) throws IOException {
    1633            long skipped = skip(input, toSkip);
    1634            if (skipped != toSkip) {
    1635                throw new EOFException("Bytes to skip: "+toSkip+" actual: "+skipped);
    1636            }
    1637        }
    1638    }