Home | History | Annotate | Download | only in io
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one or more
      3  * contributor license agreements.  See the NOTICE file distributed with
      4  * this work for additional information regarding copyright ownership.
      5  * The ASF licenses this file to You under the Apache License, Version 2.0
      6  * (the "License"); you may not use this file except in compliance with
      7  * the License.  You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 package org.apache.commons.io;
     18 
     19 import java.io.BufferedInputStream;
     20 import java.io.BufferedReader;
     21 import java.io.ByteArrayInputStream;
     22 import java.io.CharArrayWriter;
     23 import java.io.File;
     24 import java.io.IOException;
     25 import java.io.InputStream;
     26 import java.io.InputStreamReader;
     27 import java.io.OutputStream;
     28 import java.io.OutputStreamWriter;
     29 import java.io.PrintWriter;
     30 import java.io.Reader;
     31 import java.io.StringWriter;
     32 import java.io.Writer;
     33 import java.util.ArrayList;
     34 import java.util.Collection;
     35 import java.util.Iterator;
     36 import java.util.List;
     37 
     38 import org.apache.commons.io.output.ByteArrayOutputStream;
     39 
     40 /**
     41  * General IO stream manipulation utilities.
     42  * <p>
     43  * This class provides static utility methods for input/output operations.
     44  * <ul>
     45  * <li>closeQuietly - these methods close a stream ignoring nulls and exceptions
     46  * <li>toXxx/read - these methods read data from a stream
     47  * <li>write - these methods write data to a stream
     48  * <li>copy - these methods copy all the data from one stream to another
     49  * <li>contentEquals - these methods compare the content of two streams
     50  * </ul>
     51  * <p>
     52  * The byte-to-char methods and char-to-byte methods involve a conversion step.
     53  * Two methods are provided in each case, one that uses the platform default
     54  * encoding and the other which allows you to specify an encoding. You are
     55  * encouraged to always specify an encoding because relying on the platform
     56  * default can lead to unexpected results, for example when moving from
     57  * development to production.
     58  * <p>
     59  * All the methods in this class that read a stream are buffered internally.
     60  * This means that there is no cause to use a <code>BufferedInputStream</code>
     61  * or <code>BufferedReader</code>. The default buffer size of 4K has been shown
     62  * to be efficient in tests.
     63  * <p>
     64  * Wherever possible, the methods in this class do <em>not</em> flush or close
     65  * the stream. This is to avoid making non-portable assumptions about the
     66  * streams' origin and further use. Thus the caller is still responsible for
     67  * closing streams after use.
     68  * <p>
     69  * Origin of code: Excalibur.
     70  *
     71  * @author Peter Donald
     72  * @author Jeff Turner
     73  * @author Matthew Hawthorne
     74  * @author Stephen Colebourne
     75  * @author Gareth Davis
     76  * @author Ian Springer
     77  * @author Niall Pemberton
     78  * @author Sandy McArthur
     79  * @version $Id: IOUtils.java 481854 2006-12-03 18:30:07Z scolebourne $
     80  */
     81 public class IOUtils {
     82     // NOTE: This class is focussed on InputStream, OutputStream, Reader and
     83     // Writer. Each method should take at least one of these as a parameter,
     84     // or return one of them.
     85 
     86     /**
     87      * The Unix directory separator character.
     88      */
     89     public static final char DIR_SEPARATOR_UNIX = '/';
     90     /**
     91      * The Windows directory separator character.
     92      */
     93     public static final char DIR_SEPARATOR_WINDOWS = '\\';
     94     /**
     95      * The system directory separator character.
     96      */
     97     public static final char DIR_SEPARATOR = File.separatorChar;
     98     /**
     99      * The Unix line separator string.
    100      */
    101     public static final String LINE_SEPARATOR_UNIX = "\n";
    102     /**
    103      * The Windows line separator string.
    104      */
    105     public static final String LINE_SEPARATOR_WINDOWS = "\r\n";
    106     /**
    107      * The system line separator string.
    108      */
    109     public static final String LINE_SEPARATOR;
    110     static {
    111         // avoid security issues
    112         StringWriter buf = new StringWriter(4);
    113         PrintWriter out = new PrintWriter(buf);
    114         out.println();
    115         LINE_SEPARATOR = buf.toString();
    116     }
    117 
    118     /**
    119      * The default buffer size to use.
    120      */
    121     private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
    122 
    123     /**
    124      * Instances should NOT be constructed in standard programming.
    125      */
    126     public IOUtils() {
    127         super();
    128     }
    129 
    130     //-----------------------------------------------------------------------
    131     /**
    132      * Unconditionally close an <code>Reader</code>.
    133      * <p>
    134      * Equivalent to {@link Reader#close()}, except any exceptions will be ignored.
    135      * This is typically used in finally blocks.
    136      *
    137      * @param input  the Reader to close, may be null or already closed
    138      */
    139     public static void closeQuietly(Reader input) {
    140         try {
    141             if (input != null) {
    142                 input.close();
    143             }
    144         } catch (IOException ioe) {
    145             // ignore
    146         }
    147     }
    148 
    149     /**
    150      * Unconditionally close a <code>Writer</code>.
    151      * <p>
    152      * Equivalent to {@link Writer#close()}, except any exceptions will be ignored.
    153      * This is typically used in finally blocks.
    154      *
    155      * @param output  the Writer to close, may be null or already closed
    156      */
    157     public static void closeQuietly(Writer output) {
    158         try {
    159             if (output != null) {
    160                 output.close();
    161             }
    162         } catch (IOException ioe) {
    163             // ignore
    164         }
    165     }
    166 
    167     /**
    168      * Unconditionally close an <code>InputStream</code>.
    169      * <p>
    170      * Equivalent to {@link InputStream#close()}, except any exceptions will be ignored.
    171      * This is typically used in finally blocks.
    172      *
    173      * @param input  the InputStream to close, may be null or already closed
    174      */
    175     public static void closeQuietly(InputStream input) {
    176         try {
    177             if (input != null) {
    178                 input.close();
    179             }
    180         } catch (IOException ioe) {
    181             // ignore
    182         }
    183     }
    184 
    185     /**
    186      * Unconditionally close an <code>OutputStream</code>.
    187      * <p>
    188      * Equivalent to {@link OutputStream#close()}, except any exceptions will be ignored.
    189      * This is typically used in finally blocks.
    190      *
    191      * @param output  the OutputStream to close, may be null or already closed
    192      */
    193     public static void closeQuietly(OutputStream output) {
    194         try {
    195             if (output != null) {
    196                 output.close();
    197             }
    198         } catch (IOException ioe) {
    199             // ignore
    200         }
    201     }
    202 
    203     // read toByteArray
    204     //-----------------------------------------------------------------------
    205     /**
    206      * Get the contents of an <code>InputStream</code> as a <code>byte[]</code>.
    207      * <p>
    208      * This method buffers the input internally, so there is no need to use a
    209      * <code>BufferedInputStream</code>.
    210      *
    211      * @param input  the <code>InputStream</code> to read from
    212      * @return the requested byte array
    213      * @throws NullPointerException if the input is null
    214      * @throws IOException if an I/O error occurs
    215      */
    216     public static byte[] toByteArray(InputStream input) throws IOException {
    217         ByteArrayOutputStream output = new ByteArrayOutputStream();
    218         copy(input, output);
    219         return output.toByteArray();
    220     }
    221 
    222     /**
    223      * Get the contents of a <code>Reader</code> as a <code>byte[]</code>
    224      * using the default character encoding of the platform.
    225      * <p>
    226      * This method buffers the input internally, so there is no need to use a
    227      * <code>BufferedReader</code>.
    228      *
    229      * @param input  the <code>Reader</code> to read from
    230      * @return the requested byte array
    231      * @throws NullPointerException if the input is null
    232      * @throws IOException if an I/O error occurs
    233      */
    234     public static byte[] toByteArray(Reader input) throws IOException {
    235         ByteArrayOutputStream output = new ByteArrayOutputStream();
    236         copy(input, output);
    237         return output.toByteArray();
    238     }
    239 
    240     /**
    241      * Get the contents of a <code>Reader</code> as a <code>byte[]</code>
    242      * using the specified character encoding.
    243      * <p>
    244      * Character encoding names can be found at
    245      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    246      * <p>
    247      * This method buffers the input internally, so there is no need to use a
    248      * <code>BufferedReader</code>.
    249      *
    250      * @param input  the <code>Reader</code> to read from
    251      * @param encoding  the encoding to use, null means platform default
    252      * @return the requested byte array
    253      * @throws NullPointerException if the input is null
    254      * @throws IOException if an I/O error occurs
    255      * @since Commons IO 1.1
    256      */
    257     public static byte[] toByteArray(Reader input, String encoding)
    258             throws IOException {
    259         ByteArrayOutputStream output = new ByteArrayOutputStream();
    260         copy(input, output, encoding);
    261         return output.toByteArray();
    262     }
    263 
    264     /**
    265      * Get the contents of a <code>String</code> as a <code>byte[]</code>
    266      * using the default character encoding of the platform.
    267      * <p>
    268      * This is the same as {@link String#getBytes()}.
    269      *
    270      * @param input  the <code>String</code> to convert
    271      * @return the requested byte array
    272      * @throws NullPointerException if the input is null
    273      * @throws IOException if an I/O error occurs (never occurs)
    274      * @deprecated Use {@link String#getBytes()}
    275      */
    276     public static byte[] toByteArray(String input) throws IOException {
    277         return input.getBytes();
    278     }
    279 
    280     // read char[]
    281     //-----------------------------------------------------------------------
    282     /**
    283      * Get the contents of an <code>InputStream</code> as a character array
    284      * using the default character encoding of the platform.
    285      * <p>
    286      * This method buffers the input internally, so there is no need to use a
    287      * <code>BufferedInputStream</code>.
    288      *
    289      * @param is  the <code>InputStream</code> to read from
    290      * @return the requested character array
    291      * @throws NullPointerException if the input is null
    292      * @throws IOException if an I/O error occurs
    293      * @since Commons IO 1.1
    294      */
    295     public static char[] toCharArray(InputStream is) throws IOException {
    296         CharArrayWriter output = new CharArrayWriter();
    297         copy(is, output);
    298         return output.toCharArray();
    299     }
    300 
    301     /**
    302      * Get the contents of an <code>InputStream</code> as a character array
    303      * using the specified character encoding.
    304      * <p>
    305      * Character encoding names can be found at
    306      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    307      * <p>
    308      * This method buffers the input internally, so there is no need to use a
    309      * <code>BufferedInputStream</code>.
    310      *
    311      * @param is  the <code>InputStream</code> to read from
    312      * @param encoding  the encoding to use, null means platform default
    313      * @return the requested character array
    314      * @throws NullPointerException if the input is null
    315      * @throws IOException if an I/O error occurs
    316      * @since Commons IO 1.1
    317      */
    318     public static char[] toCharArray(InputStream is, String encoding)
    319             throws IOException {
    320         CharArrayWriter output = new CharArrayWriter();
    321         copy(is, output, encoding);
    322         return output.toCharArray();
    323     }
    324 
    325     /**
    326      * Get the contents of a <code>Reader</code> as a character array.
    327      * <p>
    328      * This method buffers the input internally, so there is no need to use a
    329      * <code>BufferedReader</code>.
    330      *
    331      * @param input  the <code>Reader</code> to read from
    332      * @return the requested character array
    333      * @throws NullPointerException if the input is null
    334      * @throws IOException if an I/O error occurs
    335      * @since Commons IO 1.1
    336      */
    337     public static char[] toCharArray(Reader input) throws IOException {
    338         CharArrayWriter sw = new CharArrayWriter();
    339         copy(input, sw);
    340         return sw.toCharArray();
    341     }
    342 
    343     // read toString
    344     //-----------------------------------------------------------------------
    345     /**
    346      * Get the contents of an <code>InputStream</code> as a String
    347      * using the default character encoding of the platform.
    348      * <p>
    349      * This method buffers the input internally, so there is no need to use a
    350      * <code>BufferedInputStream</code>.
    351      *
    352      * @param input  the <code>InputStream</code> to read from
    353      * @return the requested String
    354      * @throws NullPointerException if the input is null
    355      * @throws IOException if an I/O error occurs
    356      */
    357     public static String toString(InputStream input) throws IOException {
    358         StringWriter sw = new StringWriter();
    359         copy(input, sw);
    360         return sw.toString();
    361     }
    362 
    363     /**
    364      * Get the contents of an <code>InputStream</code> as a String
    365      * using the specified character encoding.
    366      * <p>
    367      * Character encoding names can be found at
    368      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    369      * <p>
    370      * This method buffers the input internally, so there is no need to use a
    371      * <code>BufferedInputStream</code>.
    372      *
    373      * @param input  the <code>InputStream</code> to read from
    374      * @param encoding  the encoding to use, null means platform default
    375      * @return the requested String
    376      * @throws NullPointerException if the input is null
    377      * @throws IOException if an I/O error occurs
    378      */
    379     public static String toString(InputStream input, String encoding)
    380             throws IOException {
    381         StringWriter sw = new StringWriter();
    382         copy(input, sw, encoding);
    383         return sw.toString();
    384     }
    385 
    386     /**
    387      * Get the contents of a <code>Reader</code> as a String.
    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      * @return the requested String
    394      * @throws NullPointerException if the input is null
    395      * @throws IOException if an I/O error occurs
    396      */
    397     public static String toString(Reader input) throws IOException {
    398         StringWriter sw = new StringWriter();
    399         copy(input, sw);
    400         return sw.toString();
    401     }
    402 
    403     /**
    404      * Get the contents of a <code>byte[]</code> as a String
    405      * using the default character encoding of the platform.
    406      *
    407      * @param input the byte array to read from
    408      * @return the requested String
    409      * @throws NullPointerException if the input is null
    410      * @throws IOException if an I/O error occurs (never occurs)
    411      * @deprecated Use {@link String#String(byte[])}
    412      */
    413     public static String toString(byte[] input) throws IOException {
    414         return new String(input);
    415     }
    416 
    417     /**
    418      * Get the contents of a <code>byte[]</code> as a String
    419      * using the specified character encoding.
    420      * <p>
    421      * Character encoding names can be found at
    422      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    423      *
    424      * @param input the byte array to read from
    425      * @param encoding  the encoding to use, null means platform default
    426      * @return the requested String
    427      * @throws NullPointerException if the input is null
    428      * @throws IOException if an I/O error occurs (never occurs)
    429      * @deprecated Use {@link String#String(byte[],String)}
    430      */
    431     public static String toString(byte[] input, String encoding)
    432             throws IOException {
    433         if (encoding == null) {
    434             return new String(input);
    435         } else {
    436             return new String(input, encoding);
    437         }
    438     }
    439 
    440     // readLines
    441     //-----------------------------------------------------------------------
    442     /**
    443      * Get the contents of an <code>InputStream</code> as a list of Strings,
    444      * one entry per line, using the default character encoding of the platform.
    445      * <p>
    446      * This method buffers the input internally, so there is no need to use a
    447      * <code>BufferedInputStream</code>.
    448      *
    449      * @param input  the <code>InputStream</code> to read from, not null
    450      * @return the list of Strings, never null
    451      * @throws NullPointerException if the input is null
    452      * @throws IOException if an I/O error occurs
    453      * @since Commons IO 1.1
    454      */
    455     public static List readLines(InputStream input) throws IOException {
    456         InputStreamReader reader = new InputStreamReader(input);
    457         return readLines(reader);
    458     }
    459 
    460     /**
    461      * Get the contents of an <code>InputStream</code> as a list of Strings,
    462      * one entry per line, using the specified character encoding.
    463      * <p>
    464      * Character encoding names can be found at
    465      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    466      * <p>
    467      * This method buffers the input internally, so there is no need to use a
    468      * <code>BufferedInputStream</code>.
    469      *
    470      * @param input  the <code>InputStream</code> to read from, not null
    471      * @param encoding  the encoding to use, null means platform default
    472      * @return the list of Strings, never null
    473      * @throws NullPointerException if the input is null
    474      * @throws IOException if an I/O error occurs
    475      * @since Commons IO 1.1
    476      */
    477     public static List readLines(InputStream input, String encoding) throws IOException {
    478         if (encoding == null) {
    479             return readLines(input);
    480         } else {
    481             InputStreamReader reader = new InputStreamReader(input, encoding);
    482             return readLines(reader);
    483         }
    484     }
    485 
    486     /**
    487      * Get the contents of a <code>Reader</code> as a list of Strings,
    488      * one entry per line.
    489      * <p>
    490      * This method buffers the input internally, so there is no need to use a
    491      * <code>BufferedReader</code>.
    492      *
    493      * @param input  the <code>Reader</code> to read from, not null
    494      * @return the list of Strings, never null
    495      * @throws NullPointerException if the input is null
    496      * @throws IOException if an I/O error occurs
    497      * @since Commons IO 1.1
    498      */
    499     public static List readLines(Reader input) throws IOException {
    500         BufferedReader reader = new BufferedReader(input);
    501         List list = new ArrayList();
    502         String line = reader.readLine();
    503         while (line != null) {
    504             list.add(line);
    505             line = reader.readLine();
    506         }
    507         return list;
    508     }
    509 
    510     // lineIterator
    511     //-----------------------------------------------------------------------
    512     /**
    513      * Return an Iterator for the lines in a <code>Reader</code>.
    514      * <p>
    515      * <code>LineIterator</code> holds a reference to the open
    516      * <code>Reader</code> specified here. When you have finished with the
    517      * iterator you should close the reader to free internal resources.
    518      * This can be done by closing the reader directly, or by calling
    519      * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
    520      * <p>
    521      * The recommended usage pattern is:
    522      * <pre>
    523      * try {
    524      *   LineIterator it = IOUtils.lineIterator(reader);
    525      *   while (it.hasNext()) {
    526      *     String line = it.nextLine();
    527      *     /// do something with line
    528      *   }
    529      * } finally {
    530      *   IOUtils.closeQuietly(reader);
    531      * }
    532      * </pre>
    533      *
    534      * @param reader  the <code>Reader</code> to read from, not null
    535      * @return an Iterator of the lines in the reader, never null
    536      * @throws IllegalArgumentException if the reader is null
    537      * @since Commons IO 1.2
    538      */
    539     public static LineIterator lineIterator(Reader reader) {
    540         return new LineIterator(reader);
    541     }
    542 
    543     /**
    544      * Return an Iterator for the lines in an <code>InputStream</code>, using
    545      * the character encoding specified (or default encoding if null).
    546      * <p>
    547      * <code>LineIterator</code> holds a reference to the open
    548      * <code>InputStream</code> specified here. When you have finished with
    549      * the iterator you should close the stream to free internal resources.
    550      * This can be done by closing the stream directly, or by calling
    551      * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
    552      * <p>
    553      * The recommended usage pattern is:
    554      * <pre>
    555      * try {
    556      *   LineIterator it = IOUtils.lineIterator(stream, "UTF-8");
    557      *   while (it.hasNext()) {
    558      *     String line = it.nextLine();
    559      *     /// do something with line
    560      *   }
    561      * } finally {
    562      *   IOUtils.closeQuietly(stream);
    563      * }
    564      * </pre>
    565      *
    566      * @param input  the <code>InputStream</code> to read from, not null
    567      * @param encoding  the encoding to use, null means platform default
    568      * @return an Iterator of the lines in the reader, never null
    569      * @throws IllegalArgumentException if the input is null
    570      * @throws IOException if an I/O error occurs, such as if the encoding is invalid
    571      * @since Commons IO 1.2
    572      */
    573     public static LineIterator lineIterator(InputStream input, String encoding)
    574                      throws IOException {
    575         Reader reader = null;
    576         if (encoding == null) {
    577             reader = new InputStreamReader(input);
    578         } else {
    579             reader = new InputStreamReader(input, encoding);
    580         }
    581         return new LineIterator(reader);
    582     }
    583 
    584     //-----------------------------------------------------------------------
    585     /**
    586      * Convert the specified string to an input stream, encoded as bytes
    587      * using the default character encoding of the platform.
    588      *
    589      * @param input the string to convert
    590      * @return an input stream
    591      * @since Commons IO 1.1
    592      */
    593     public static InputStream toInputStream(String input) {
    594         byte[] bytes = input.getBytes();
    595         return new ByteArrayInputStream(bytes);
    596     }
    597 
    598     /**
    599      * Convert the specified string to an input stream, encoded as bytes
    600      * using the specified character encoding.
    601      * <p>
    602      * Character encoding names can be found at
    603      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    604      *
    605      * @param input the string to convert
    606      * @param encoding the encoding to use, null means platform default
    607      * @throws IOException if the encoding is invalid
    608      * @return an input stream
    609      * @since Commons IO 1.1
    610      */
    611     public static InputStream toInputStream(String input, String encoding) throws IOException {
    612         byte[] bytes = encoding != null ? input.getBytes(encoding) : input.getBytes();
    613         return new ByteArrayInputStream(bytes);
    614     }
    615 
    616     // write byte[]
    617     //-----------------------------------------------------------------------
    618     /**
    619      * Writes bytes from a <code>byte[]</code> to an <code>OutputStream</code>.
    620      *
    621      * @param data  the byte array to write, do not modify during output,
    622      * null ignored
    623      * @param output  the <code>OutputStream</code> to write to
    624      * @throws NullPointerException if output is null
    625      * @throws IOException if an I/O error occurs
    626      * @since Commons IO 1.1
    627      */
    628     public static void write(byte[] data, OutputStream output)
    629             throws IOException {
    630         if (data != null) {
    631             output.write(data);
    632         }
    633     }
    634 
    635     /**
    636      * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code>
    637      * using the default character encoding of the platform.
    638      * <p>
    639      * This method uses {@link String#String(byte[])}.
    640      *
    641      * @param data  the byte array to write, do not modify during output,
    642      * null ignored
    643      * @param output  the <code>Writer</code> to write to
    644      * @throws NullPointerException if output is null
    645      * @throws IOException if an I/O error occurs
    646      * @since Commons IO 1.1
    647      */
    648     public static void write(byte[] data, Writer output) throws IOException {
    649         if (data != null) {
    650             output.write(new String(data));
    651         }
    652     }
    653 
    654     /**
    655      * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code>
    656      * using the specified character encoding.
    657      * <p>
    658      * Character encoding names can be found at
    659      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    660      * <p>
    661      * This method uses {@link String#String(byte[], String)}.
    662      *
    663      * @param data  the byte array to write, do not modify during output,
    664      * null ignored
    665      * @param output  the <code>Writer</code> to write to
    666      * @param encoding  the encoding to use, null means platform default
    667      * @throws NullPointerException if output is null
    668      * @throws IOException if an I/O error occurs
    669      * @since Commons IO 1.1
    670      */
    671     public static void write(byte[] data, Writer output, String encoding)
    672             throws IOException {
    673         if (data != null) {
    674             if (encoding == null) {
    675                 write(data, output);
    676             } else {
    677                 output.write(new String(data, encoding));
    678             }
    679         }
    680     }
    681 
    682     // write char[]
    683     //-----------------------------------------------------------------------
    684     /**
    685      * Writes chars from a <code>char[]</code> to a <code>Writer</code>
    686      * using the default character encoding of the platform.
    687      *
    688      * @param data  the char array to write, do not modify during output,
    689      * null ignored
    690      * @param output  the <code>Writer</code> to write to
    691      * @throws NullPointerException if output is null
    692      * @throws IOException if an I/O error occurs
    693      * @since Commons IO 1.1
    694      */
    695     public static void write(char[] data, Writer output) throws IOException {
    696         if (data != null) {
    697             output.write(data);
    698         }
    699     }
    700 
    701     /**
    702      * Writes chars from a <code>char[]</code> to bytes on an
    703      * <code>OutputStream</code>.
    704      * <p>
    705      * This method uses {@link String#String(char[])} and
    706      * {@link String#getBytes()}.
    707      *
    708      * @param data  the char array to write, do not modify during output,
    709      * null ignored
    710      * @param output  the <code>OutputStream</code> to write to
    711      * @throws NullPointerException if output is null
    712      * @throws IOException if an I/O error occurs
    713      * @since Commons IO 1.1
    714      */
    715     public static void write(char[] data, OutputStream output)
    716             throws IOException {
    717         if (data != null) {
    718             output.write(new String(data).getBytes());
    719         }
    720     }
    721 
    722     /**
    723      * Writes chars from a <code>char[]</code> to bytes on an
    724      * <code>OutputStream</code> using the specified character encoding.
    725      * <p>
    726      * Character encoding names can be found at
    727      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    728      * <p>
    729      * This method uses {@link String#String(char[])} and
    730      * {@link String#getBytes(String)}.
    731      *
    732      * @param data  the char array to write, do not modify during output,
    733      * null ignored
    734      * @param output  the <code>OutputStream</code> to write to
    735      * @param encoding  the encoding to use, null means platform default
    736      * @throws NullPointerException if output is null
    737      * @throws IOException if an I/O error occurs
    738      * @since Commons IO 1.1
    739      */
    740     public static void write(char[] data, OutputStream output, String encoding)
    741             throws IOException {
    742         if (data != null) {
    743             if (encoding == null) {
    744                 write(data, output);
    745             } else {
    746                 output.write(new String(data).getBytes(encoding));
    747             }
    748         }
    749     }
    750 
    751     // write String
    752     //-----------------------------------------------------------------------
    753     /**
    754      * Writes chars from a <code>String</code> to a <code>Writer</code>.
    755      *
    756      * @param data  the <code>String</code> to write, null ignored
    757      * @param output  the <code>Writer</code> to write to
    758      * @throws NullPointerException if output is null
    759      * @throws IOException if an I/O error occurs
    760      * @since Commons IO 1.1
    761      */
    762     public static void write(String data, Writer output) throws IOException {
    763         if (data != null) {
    764             output.write(data);
    765         }
    766     }
    767 
    768     /**
    769      * Writes chars from a <code>String</code> to bytes on an
    770      * <code>OutputStream</code> using the default character encoding of the
    771      * platform.
    772      * <p>
    773      * This method uses {@link String#getBytes()}.
    774      *
    775      * @param data  the <code>String</code> to write, null ignored
    776      * @param output  the <code>OutputStream</code> to write to
    777      * @throws NullPointerException if output is null
    778      * @throws IOException if an I/O error occurs
    779      * @since Commons IO 1.1
    780      */
    781     public static void write(String data, OutputStream output)
    782             throws IOException {
    783         if (data != null) {
    784             output.write(data.getBytes());
    785         }
    786     }
    787 
    788     /**
    789      * Writes chars from a <code>String</code> to bytes on an
    790      * <code>OutputStream</code> using the specified character encoding.
    791      * <p>
    792      * Character encoding names can be found at
    793      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    794      * <p>
    795      * This method uses {@link String#getBytes(String)}.
    796      *
    797      * @param data  the <code>String</code> to write, null ignored
    798      * @param output  the <code>OutputStream</code> to write to
    799      * @param encoding  the encoding to use, null means platform default
    800      * @throws NullPointerException if output is null
    801      * @throws IOException if an I/O error occurs
    802      * @since Commons IO 1.1
    803      */
    804     public static void write(String data, OutputStream output, String encoding)
    805             throws IOException {
    806         if (data != null) {
    807             if (encoding == null) {
    808                 write(data, output);
    809             } else {
    810                 output.write(data.getBytes(encoding));
    811             }
    812         }
    813     }
    814 
    815     // write StringBuffer
    816     //-----------------------------------------------------------------------
    817     /**
    818      * Writes chars from a <code>StringBuffer</code> to a <code>Writer</code>.
    819      *
    820      * @param data  the <code>StringBuffer</code> to write, null ignored
    821      * @param output  the <code>Writer</code> to write to
    822      * @throws NullPointerException if output is null
    823      * @throws IOException if an I/O error occurs
    824      * @since Commons IO 1.1
    825      */
    826     public static void write(StringBuffer data, Writer output)
    827             throws IOException {
    828         if (data != null) {
    829             output.write(data.toString());
    830         }
    831     }
    832 
    833     /**
    834      * Writes chars from a <code>StringBuffer</code> to bytes on an
    835      * <code>OutputStream</code> using the default character encoding of the
    836      * platform.
    837      * <p>
    838      * This method uses {@link String#getBytes()}.
    839      *
    840      * @param data  the <code>StringBuffer</code> to write, null ignored
    841      * @param output  the <code>OutputStream</code> to write to
    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(StringBuffer data, OutputStream output)
    847             throws IOException {
    848         if (data != null) {
    849             output.write(data.toString().getBytes());
    850         }
    851     }
    852 
    853     /**
    854      * Writes chars from a <code>StringBuffer</code> to bytes on an
    855      * <code>OutputStream</code> using the specified character encoding.
    856      * <p>
    857      * Character encoding names can be found at
    858      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    859      * <p>
    860      * This method uses {@link String#getBytes(String)}.
    861      *
    862      * @param data  the <code>StringBuffer</code> to write, null ignored
    863      * @param output  the <code>OutputStream</code> to write to
    864      * @param encoding  the encoding to use, null means platform default
    865      * @throws NullPointerException if output is null
    866      * @throws IOException if an I/O error occurs
    867      * @since Commons IO 1.1
    868      */
    869     public static void write(StringBuffer data, OutputStream output,
    870             String encoding) throws IOException {
    871         if (data != null) {
    872             if (encoding == null) {
    873                 write(data, output);
    874             } else {
    875                 output.write(data.toString().getBytes(encoding));
    876             }
    877         }
    878     }
    879 
    880     // writeLines
    881     //-----------------------------------------------------------------------
    882     /**
    883      * Writes the <code>toString()</code> value of each item in a collection to
    884      * an <code>OutputStream</code> line by line, using the default character
    885      * encoding of the platform and the specified line ending.
    886      *
    887      * @param lines  the lines to write, null entries produce blank lines
    888      * @param lineEnding  the line separator to use, null is system default
    889      * @param output  the <code>OutputStream</code> to write to, not null, not closed
    890      * @throws NullPointerException if the output is null
    891      * @throws IOException if an I/O error occurs
    892      * @since Commons IO 1.1
    893      */
    894     public static void writeLines(Collection lines, String lineEnding,
    895             OutputStream output) throws IOException {
    896         if (lines == null) {
    897             return;
    898         }
    899         if (lineEnding == null) {
    900             lineEnding = LINE_SEPARATOR;
    901         }
    902         for (Iterator it = lines.iterator(); it.hasNext(); ) {
    903             Object line = it.next();
    904             if (line != null) {
    905                 output.write(line.toString().getBytes());
    906             }
    907             output.write(lineEnding.getBytes());
    908         }
    909     }
    910 
    911     /**
    912      * Writes the <code>toString()</code> value of each item in a collection to
    913      * an <code>OutputStream</code> line by line, using the specified character
    914      * encoding and the specified line ending.
    915      * <p>
    916      * Character encoding names can be found at
    917      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    918      *
    919      * @param lines  the lines to write, null entries produce blank lines
    920      * @param lineEnding  the line separator to use, null is system default
    921      * @param output  the <code>OutputStream</code> to write to, not null, not closed
    922      * @param encoding  the encoding to use, null means platform default
    923      * @throws NullPointerException if the output is null
    924      * @throws IOException if an I/O error occurs
    925      * @since Commons IO 1.1
    926      */
    927     public static void writeLines(Collection lines, String lineEnding,
    928             OutputStream output, String encoding) throws IOException {
    929         if (encoding == null) {
    930             writeLines(lines, lineEnding, output);
    931         } else {
    932             if (lines == null) {
    933                 return;
    934             }
    935             if (lineEnding == null) {
    936                 lineEnding = LINE_SEPARATOR;
    937             }
    938             for (Iterator it = lines.iterator(); it.hasNext(); ) {
    939                 Object line = it.next();
    940                 if (line != null) {
    941                     output.write(line.toString().getBytes(encoding));
    942                 }
    943                 output.write(lineEnding.getBytes(encoding));
    944             }
    945         }
    946     }
    947 
    948     /**
    949      * Writes the <code>toString()</code> value of each item in a collection to
    950      * a <code>Writer</code> line by line, using the specified line ending.
    951      *
    952      * @param lines  the lines to write, null entries produce blank lines
    953      * @param lineEnding  the line separator to use, null is system default
    954      * @param writer  the <code>Writer</code> to write to, not null, not closed
    955      * @throws NullPointerException if the input is null
    956      * @throws IOException if an I/O error occurs
    957      * @since Commons IO 1.1
    958      */
    959     public static void writeLines(Collection lines, String lineEnding,
    960             Writer writer) throws IOException {
    961         if (lines == null) {
    962             return;
    963         }
    964         if (lineEnding == null) {
    965             lineEnding = LINE_SEPARATOR;
    966         }
    967         for (Iterator it = lines.iterator(); it.hasNext(); ) {
    968             Object line = it.next();
    969             if (line != null) {
    970                 writer.write(line.toString());
    971             }
    972             writer.write(lineEnding);
    973         }
    974     }
    975 
    976     // copy from InputStream
    977     //-----------------------------------------------------------------------
    978     /**
    979      * Copy bytes from an <code>InputStream</code> to an
    980      * <code>OutputStream</code>.
    981      * <p>
    982      * This method buffers the input internally, so there is no need to use a
    983      * <code>BufferedInputStream</code>.
    984      * <p>
    985      * Large streams (over 2GB) will return a bytes copied value of
    986      * <code>-1</code> after the copy has completed since the correct
    987      * number of bytes cannot be returned as an int. For large streams
    988      * use the <code>copyLarge(InputStream, OutputStream)</code> method.
    989      *
    990      * @param input  the <code>InputStream</code> to read from
    991      * @param output  the <code>OutputStream</code> to write to
    992      * @return the number of bytes copied
    993      * @throws NullPointerException if the input or output is null
    994      * @throws IOException if an I/O error occurs
    995      * @throws ArithmeticException if the byte count is too large
    996      * @since Commons IO 1.1
    997      */
    998     public static int copy(InputStream input, OutputStream output) throws IOException {
    999         long count = copyLarge(input, output);
   1000         if (count > Integer.MAX_VALUE) {
   1001             return -1;
   1002         }
   1003         return (int) count;
   1004     }
   1005 
   1006     /**
   1007      * Copy bytes from a large (over 2GB) <code>InputStream</code> to an
   1008      * <code>OutputStream</code>.
   1009      * <p>
   1010      * This method buffers the input internally, so there is no need to use a
   1011      * <code>BufferedInputStream</code>.
   1012      *
   1013      * @param input  the <code>InputStream</code> to read from
   1014      * @param output  the <code>OutputStream</code> to write to
   1015      * @return the number of bytes copied
   1016      * @throws NullPointerException if the input or output is null
   1017      * @throws IOException if an I/O error occurs
   1018      * @since Commons IO 1.3
   1019      */
   1020     public static long copyLarge(InputStream input, OutputStream output)
   1021             throws IOException {
   1022         byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
   1023         long count = 0;
   1024         int n = 0;
   1025         while (-1 != (n = input.read(buffer))) {
   1026             output.write(buffer, 0, n);
   1027             count += n;
   1028         }
   1029         return count;
   1030     }
   1031 
   1032     /**
   1033      * Copy bytes from an <code>InputStream</code> to chars on a
   1034      * <code>Writer</code> using the default character encoding of the platform.
   1035      * <p>
   1036      * This method buffers the input internally, so there is no need to use a
   1037      * <code>BufferedInputStream</code>.
   1038      * <p>
   1039      * This method uses {@link InputStreamReader}.
   1040      *
   1041      * @param input  the <code>InputStream</code> to read from
   1042      * @param output  the <code>Writer</code> to write to
   1043      * @throws NullPointerException if the input or output is null
   1044      * @throws IOException if an I/O error occurs
   1045      * @since Commons IO 1.1
   1046      */
   1047     public static void copy(InputStream input, Writer output)
   1048             throws IOException {
   1049         InputStreamReader in = new InputStreamReader(input);
   1050         copy(in, output);
   1051     }
   1052 
   1053     /**
   1054      * Copy bytes from an <code>InputStream</code> to chars on a
   1055      * <code>Writer</code> using the specified character encoding.
   1056      * <p>
   1057      * This method buffers the input internally, so there is no need to use a
   1058      * <code>BufferedInputStream</code>.
   1059      * <p>
   1060      * Character encoding names can be found at
   1061      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
   1062      * <p>
   1063      * This method uses {@link InputStreamReader}.
   1064      *
   1065      * @param input  the <code>InputStream</code> to read from
   1066      * @param output  the <code>Writer</code> to write to
   1067      * @param encoding  the encoding to use, null means platform default
   1068      * @throws NullPointerException if the input or output is null
   1069      * @throws IOException if an I/O error occurs
   1070      * @since Commons IO 1.1
   1071      */
   1072     public static void copy(InputStream input, Writer output, String encoding)
   1073             throws IOException {
   1074         if (encoding == null) {
   1075             copy(input, output);
   1076         } else {
   1077             InputStreamReader in = new InputStreamReader(input, encoding);
   1078             copy(in, output);
   1079         }
   1080     }
   1081 
   1082     // copy from Reader
   1083     //-----------------------------------------------------------------------
   1084     /**
   1085      * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
   1086      * <p>
   1087      * This method buffers the input internally, so there is no need to use a
   1088      * <code>BufferedReader</code>.
   1089      * <p>
   1090      * Large streams (over 2GB) will return a chars copied value of
   1091      * <code>-1</code> after the copy has completed since the correct
   1092      * number of chars cannot be returned as an int. For large streams
   1093      * use the <code>copyLarge(Reader, Writer)</code> method.
   1094      *
   1095      * @param input  the <code>Reader</code> to read from
   1096      * @param output  the <code>Writer</code> to write to
   1097      * @return the number of characters copied
   1098      * @throws NullPointerException if the input or output is null
   1099      * @throws IOException if an I/O error occurs
   1100      * @throws ArithmeticException if the character count is too large
   1101      * @since Commons IO 1.1
   1102      */
   1103     public static int copy(Reader input, Writer output) throws IOException {
   1104         long count = copyLarge(input, output);
   1105         if (count > Integer.MAX_VALUE) {
   1106             return -1;
   1107         }
   1108         return (int) count;
   1109     }
   1110 
   1111     /**
   1112      * Copy chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>.
   1113      * <p>
   1114      * This method buffers the input internally, so there is no need to use a
   1115      * <code>BufferedReader</code>.
   1116      *
   1117      * @param input  the <code>Reader</code> to read from
   1118      * @param output  the <code>Writer</code> to write to
   1119      * @return the number of characters copied
   1120      * @throws NullPointerException if the input or output is null
   1121      * @throws IOException if an I/O error occurs
   1122      * @since Commons IO 1.3
   1123      */
   1124     public static long copyLarge(Reader input, Writer output) throws IOException {
   1125         char[] buffer = new char[DEFAULT_BUFFER_SIZE];
   1126         long count = 0;
   1127         int n = 0;
   1128         while (-1 != (n = input.read(buffer))) {
   1129             output.write(buffer, 0, n);
   1130             count += n;
   1131         }
   1132         return count;
   1133     }
   1134 
   1135     /**
   1136      * Copy chars from a <code>Reader</code> to bytes on an
   1137      * <code>OutputStream</code> using the default character encoding of the
   1138      * platform, and calling flush.
   1139      * <p>
   1140      * This method buffers the input internally, so there is no need to use a
   1141      * <code>BufferedReader</code>.
   1142      * <p>
   1143      * Due to the implementation of OutputStreamWriter, this method performs a
   1144      * flush.
   1145      * <p>
   1146      * This method uses {@link OutputStreamWriter}.
   1147      *
   1148      * @param input  the <code>Reader</code> to read from
   1149      * @param output  the <code>OutputStream</code> to write to
   1150      * @throws NullPointerException if the input or output is null
   1151      * @throws IOException if an I/O error occurs
   1152      * @since Commons IO 1.1
   1153      */
   1154     public static void copy(Reader input, OutputStream output)
   1155             throws IOException {
   1156         OutputStreamWriter out = new OutputStreamWriter(output);
   1157         copy(input, out);
   1158         // XXX Unless anyone is planning on rewriting OutputStreamWriter, we
   1159         // have to flush here.
   1160         out.flush();
   1161     }
   1162 
   1163     /**
   1164      * Copy chars from a <code>Reader</code> to bytes on an
   1165      * <code>OutputStream</code> using the specified character encoding, and
   1166      * calling flush.
   1167      * <p>
   1168      * This method buffers the input internally, so there is no need to use a
   1169      * <code>BufferedReader</code>.
   1170      * <p>
   1171      * Character encoding names can be found at
   1172      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
   1173      * <p>
   1174      * Due to the implementation of OutputStreamWriter, this method performs a
   1175      * flush.
   1176      * <p>
   1177      * This method uses {@link OutputStreamWriter}.
   1178      *
   1179      * @param input  the <code>Reader</code> to read from
   1180      * @param output  the <code>OutputStream</code> to write to
   1181      * @param encoding  the encoding to use, null means platform default
   1182      * @throws NullPointerException if the input or output is null
   1183      * @throws IOException if an I/O error occurs
   1184      * @since Commons IO 1.1
   1185      */
   1186     public static void copy(Reader input, OutputStream output, String encoding)
   1187             throws IOException {
   1188         if (encoding == null) {
   1189             copy(input, output);
   1190         } else {
   1191             OutputStreamWriter out = new OutputStreamWriter(output, encoding);
   1192             copy(input, out);
   1193             // XXX Unless anyone is planning on rewriting OutputStreamWriter,
   1194             // we have to flush here.
   1195             out.flush();
   1196         }
   1197     }
   1198 
   1199     // content equals
   1200     //-----------------------------------------------------------------------
   1201     /**
   1202      * Compare the contents of two Streams to determine if they are equal or
   1203      * not.
   1204      * <p>
   1205      * This method buffers the input internally using
   1206      * <code>BufferedInputStream</code> if they are not already buffered.
   1207      *
   1208      * @param input1  the first stream
   1209      * @param input2  the second stream
   1210      * @return true if the content of the streams are equal or they both don't
   1211      * exist, false otherwise
   1212      * @throws NullPointerException if either input is null
   1213      * @throws IOException if an I/O error occurs
   1214      */
   1215     public static boolean contentEquals(InputStream input1, InputStream input2)
   1216             throws IOException {
   1217         if (!(input1 instanceof BufferedInputStream)) {
   1218             input1 = new BufferedInputStream(input1);
   1219         }
   1220         if (!(input2 instanceof BufferedInputStream)) {
   1221             input2 = new BufferedInputStream(input2);
   1222         }
   1223 
   1224         int ch = input1.read();
   1225         while (-1 != ch) {
   1226             int ch2 = input2.read();
   1227             if (ch != ch2) {
   1228                 return false;
   1229             }
   1230             ch = input1.read();
   1231         }
   1232 
   1233         int ch2 = input2.read();
   1234         return (ch2 == -1);
   1235     }
   1236 
   1237     /**
   1238      * Compare the contents of two Readers to determine if they are equal or
   1239      * not.
   1240      * <p>
   1241      * This method buffers the input internally using
   1242      * <code>BufferedReader</code> if they are not already buffered.
   1243      *
   1244      * @param input1  the first reader
   1245      * @param input2  the second reader
   1246      * @return true if the content of the readers are equal or they both don't
   1247      * exist, false otherwise
   1248      * @throws NullPointerException if either input is null
   1249      * @throws IOException if an I/O error occurs
   1250      * @since Commons IO 1.1
   1251      */
   1252     public static boolean contentEquals(Reader input1, Reader input2)
   1253             throws IOException {
   1254         if (!(input1 instanceof BufferedReader)) {
   1255             input1 = new BufferedReader(input1);
   1256         }
   1257         if (!(input2 instanceof BufferedReader)) {
   1258             input2 = new BufferedReader(input2);
   1259         }
   1260 
   1261         int ch = input1.read();
   1262         while (-1 != ch) {
   1263             int ch2 = input2.read();
   1264             if (ch != ch2) {
   1265                 return false;
   1266             }
   1267             ch = input1.read();
   1268         }
   1269 
   1270         int ch2 = input2.read();
   1271         return (ch2 == -1);
   1272     }
   1273 
   1274 }
   1275