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     @Deprecated
    277     public static byte[] toByteArray(String input) throws IOException {
    278         return input.getBytes();
    279     }
    280 
    281     // read char[]
    282     //-----------------------------------------------------------------------
    283     /**
    284      * Get the contents of an <code>InputStream</code> as a character array
    285      * using the default character encoding of the platform.
    286      * <p>
    287      * This method buffers the input internally, so there is no need to use a
    288      * <code>BufferedInputStream</code>.
    289      *
    290      * @param is  the <code>InputStream</code> to read from
    291      * @return the requested character array
    292      * @throws NullPointerException if the input is null
    293      * @throws IOException if an I/O error occurs
    294      * @since Commons IO 1.1
    295      */
    296     public static char[] toCharArray(InputStream is) throws IOException {
    297         CharArrayWriter output = new CharArrayWriter();
    298         copy(is, output);
    299         return output.toCharArray();
    300     }
    301 
    302     /**
    303      * Get the contents of an <code>InputStream</code> as a character array
    304      * using the specified character encoding.
    305      * <p>
    306      * Character encoding names can be found at
    307      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    308      * <p>
    309      * This method buffers the input internally, so there is no need to use a
    310      * <code>BufferedInputStream</code>.
    311      *
    312      * @param is  the <code>InputStream</code> to read from
    313      * @param encoding  the encoding to use, null means platform default
    314      * @return the requested character array
    315      * @throws NullPointerException if the input is null
    316      * @throws IOException if an I/O error occurs
    317      * @since Commons IO 1.1
    318      */
    319     public static char[] toCharArray(InputStream is, String encoding)
    320             throws IOException {
    321         CharArrayWriter output = new CharArrayWriter();
    322         copy(is, output, encoding);
    323         return output.toCharArray();
    324     }
    325 
    326     /**
    327      * Get the contents of a <code>Reader</code> as a character array.
    328      * <p>
    329      * This method buffers the input internally, so there is no need to use a
    330      * <code>BufferedReader</code>.
    331      *
    332      * @param input  the <code>Reader</code> to read from
    333      * @return the requested character array
    334      * @throws NullPointerException if the input is null
    335      * @throws IOException if an I/O error occurs
    336      * @since Commons IO 1.1
    337      */
    338     public static char[] toCharArray(Reader input) throws IOException {
    339         CharArrayWriter sw = new CharArrayWriter();
    340         copy(input, sw);
    341         return sw.toCharArray();
    342     }
    343 
    344     // read toString
    345     //-----------------------------------------------------------------------
    346     /**
    347      * Get the contents of an <code>InputStream</code> as a String
    348      * using the default character encoding of the platform.
    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 String
    355      * @throws NullPointerException if the input is null
    356      * @throws IOException if an I/O error occurs
    357      */
    358     public static String toString(InputStream input) throws IOException {
    359         StringWriter sw = new StringWriter();
    360         copy(input, sw);
    361         return sw.toString();
    362     }
    363 
    364     /**
    365      * Get the contents of an <code>InputStream</code> as a String
    366      * using the specified character encoding.
    367      * <p>
    368      * Character encoding names can be found at
    369      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    370      * <p>
    371      * This method buffers the input internally, so there is no need to use a
    372      * <code>BufferedInputStream</code>.
    373      *
    374      * @param input  the <code>InputStream</code> to read from
    375      * @param encoding  the encoding to use, null means platform default
    376      * @return the requested String
    377      * @throws NullPointerException if the input is null
    378      * @throws IOException if an I/O error occurs
    379      */
    380     public static String toString(InputStream input, String encoding)
    381             throws IOException {
    382         StringWriter sw = new StringWriter();
    383         copy(input, sw, encoding);
    384         return sw.toString();
    385     }
    386 
    387     /**
    388      * Get the contents of a <code>Reader</code> as a String.
    389      * <p>
    390      * This method buffers the input internally, so there is no need to use a
    391      * <code>BufferedReader</code>.
    392      *
    393      * @param input  the <code>Reader</code> to read from
    394      * @return the requested String
    395      * @throws NullPointerException if the input is null
    396      * @throws IOException if an I/O error occurs
    397      */
    398     public static String toString(Reader input) throws IOException {
    399         StringWriter sw = new StringWriter();
    400         copy(input, sw);
    401         return sw.toString();
    402     }
    403 
    404     /**
    405      * Get the contents of a <code>byte[]</code> as a String
    406      * using the default character encoding of the platform.
    407      *
    408      * @param input the byte array to read from
    409      * @return the requested String
    410      * @throws NullPointerException if the input is null
    411      * @throws IOException if an I/O error occurs (never occurs)
    412      * @deprecated Use {@link String#String(byte[])}
    413      */
    414     @Deprecated
    415     public static String toString(byte[] input) throws IOException {
    416         return new String(input);
    417     }
    418 
    419     /**
    420      * Get the contents of a <code>byte[]</code> as a String
    421      * using the specified character encoding.
    422      * <p>
    423      * Character encoding names can be found at
    424      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    425      *
    426      * @param input the byte array to read from
    427      * @param encoding  the encoding to use, null means platform default
    428      * @return the requested String
    429      * @throws NullPointerException if the input is null
    430      * @throws IOException if an I/O error occurs (never occurs)
    431      * @deprecated Use {@link String#String(byte[],String)}
    432      */
    433     @Deprecated
    434     public static String toString(byte[] input, String encoding)
    435             throws IOException {
    436         if (encoding == null) {
    437             return new String(input);
    438         } else {
    439             return new String(input, encoding);
    440         }
    441     }
    442 
    443     // readLines
    444     //-----------------------------------------------------------------------
    445     /**
    446      * Get the contents of an <code>InputStream</code> as a list of Strings,
    447      * one entry per line, using the default character encoding of the platform.
    448      * <p>
    449      * This method buffers the input internally, so there is no need to use a
    450      * <code>BufferedInputStream</code>.
    451      *
    452      * @param input  the <code>InputStream</code> to read from, not null
    453      * @return the list of Strings, never null
    454      * @throws NullPointerException if the input is null
    455      * @throws IOException if an I/O error occurs
    456      * @since Commons IO 1.1
    457      */
    458     public static List<String> readLines(InputStream input) throws IOException {
    459         InputStreamReader reader = new InputStreamReader(input);
    460         return readLines(reader);
    461     }
    462 
    463     /**
    464      * Get the contents of an <code>InputStream</code> as a list of Strings,
    465      * one entry per line, using the specified character encoding.
    466      * <p>
    467      * Character encoding names can be found at
    468      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    469      * <p>
    470      * This method buffers the input internally, so there is no need to use a
    471      * <code>BufferedInputStream</code>.
    472      *
    473      * @param input  the <code>InputStream</code> to read from, not null
    474      * @param encoding  the encoding to use, null means platform default
    475      * @return the list of Strings, never null
    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 List<String> readLines(InputStream input, String encoding) throws IOException {
    481         if (encoding == null) {
    482             return readLines(input);
    483         } else {
    484             InputStreamReader reader = new InputStreamReader(input, encoding);
    485             return readLines(reader);
    486         }
    487     }
    488 
    489     /**
    490      * Get the contents of a <code>Reader</code> as a list of Strings,
    491      * one entry per line.
    492      * <p>
    493      * This method buffers the input internally, so there is no need to use a
    494      * <code>BufferedReader</code>.
    495      *
    496      * @param input  the <code>Reader</code> to read from, not null
    497      * @return the list of Strings, never null
    498      * @throws NullPointerException if the input is null
    499      * @throws IOException if an I/O error occurs
    500      * @since Commons IO 1.1
    501      */
    502     public static List<String> readLines(Reader input) throws IOException {
    503         BufferedReader reader = new BufferedReader(input);
    504         List<String> list = new ArrayList<String>();
    505         String line = reader.readLine();
    506         while (line != null) {
    507             list.add(line);
    508             line = reader.readLine();
    509         }
    510         return list;
    511     }
    512 
    513     // lineIterator
    514     //-----------------------------------------------------------------------
    515     /**
    516      * Return an Iterator for the lines in a <code>Reader</code>.
    517      * <p>
    518      * <code>LineIterator</code> holds a reference to the open
    519      * <code>Reader</code> specified here. When you have finished with the
    520      * iterator you should close the reader to free internal resources.
    521      * This can be done by closing the reader directly, or by calling
    522      * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
    523      * <p>
    524      * The recommended usage pattern is:
    525      * <pre>
    526      * try {
    527      *   LineIterator it = IOUtils.lineIterator(reader);
    528      *   while (it.hasNext()) {
    529      *     String line = it.nextLine();
    530      *     /// do something with line
    531      *   }
    532      * } finally {
    533      *   IOUtils.closeQuietly(reader);
    534      * }
    535      * </pre>
    536      *
    537      * @param reader  the <code>Reader</code> to read from, not null
    538      * @return an Iterator of the lines in the reader, never null
    539      * @throws IllegalArgumentException if the reader is null
    540      * @since Commons IO 1.2
    541      */
    542     public static LineIterator lineIterator(Reader reader) {
    543         return new LineIterator(reader);
    544     }
    545 
    546     /**
    547      * Return an Iterator for the lines in an <code>InputStream</code>, using
    548      * the character encoding specified (or default encoding if null).
    549      * <p>
    550      * <code>LineIterator</code> holds a reference to the open
    551      * <code>InputStream</code> specified here. When you have finished with
    552      * the iterator you should close the stream to free internal resources.
    553      * This can be done by closing the stream directly, or by calling
    554      * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
    555      * <p>
    556      * The recommended usage pattern is:
    557      * <pre>
    558      * try {
    559      *   LineIterator it = IOUtils.lineIterator(stream, "UTF-8");
    560      *   while (it.hasNext()) {
    561      *     String line = it.nextLine();
    562      *     /// do something with line
    563      *   }
    564      * } finally {
    565      *   IOUtils.closeQuietly(stream);
    566      * }
    567      * </pre>
    568      *
    569      * @param input  the <code>InputStream</code> to read from, not null
    570      * @param encoding  the encoding to use, null means platform default
    571      * @return an Iterator of the lines in the reader, never null
    572      * @throws IllegalArgumentException if the input is null
    573      * @throws IOException if an I/O error occurs, such as if the encoding is invalid
    574      * @since Commons IO 1.2
    575      */
    576     public static LineIterator lineIterator(InputStream input, String encoding)
    577                      throws IOException {
    578         Reader reader = null;
    579         if (encoding == null) {
    580             reader = new InputStreamReader(input);
    581         } else {
    582             reader = new InputStreamReader(input, encoding);
    583         }
    584         return new LineIterator(reader);
    585     }
    586 
    587     //-----------------------------------------------------------------------
    588     /**
    589      * Convert the specified string to an input stream, encoded as bytes
    590      * using the default character encoding of the platform.
    591      *
    592      * @param input the string to convert
    593      * @return an input stream
    594      * @since Commons IO 1.1
    595      */
    596     public static InputStream toInputStream(String input) {
    597         byte[] bytes = input.getBytes();
    598         return new ByteArrayInputStream(bytes);
    599     }
    600 
    601     /**
    602      * Convert the specified string to an input stream, encoded as bytes
    603      * using the specified character encoding.
    604      * <p>
    605      * Character encoding names can be found at
    606      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    607      *
    608      * @param input the string to convert
    609      * @param encoding the encoding to use, null means platform default
    610      * @throws IOException if the encoding is invalid
    611      * @return an input stream
    612      * @since Commons IO 1.1
    613      */
    614     public static InputStream toInputStream(String input, String encoding) throws IOException {
    615         byte[] bytes = encoding != null ? input.getBytes(encoding) : input.getBytes();
    616         return new ByteArrayInputStream(bytes);
    617     }
    618 
    619     // write byte[]
    620     //-----------------------------------------------------------------------
    621     /**
    622      * Writes bytes from a <code>byte[]</code> to an <code>OutputStream</code>.
    623      *
    624      * @param data  the byte array to write, do not modify during output,
    625      * null ignored
    626      * @param output  the <code>OutputStream</code> to write to
    627      * @throws NullPointerException if output is null
    628      * @throws IOException if an I/O error occurs
    629      * @since Commons IO 1.1
    630      */
    631     public static void write(byte[] data, OutputStream output)
    632             throws IOException {
    633         if (data != null) {
    634             output.write(data);
    635         }
    636     }
    637 
    638     /**
    639      * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code>
    640      * using the default character encoding of the platform.
    641      * <p>
    642      * This method uses {@link String#String(byte[])}.
    643      *
    644      * @param data  the byte array to write, do not modify during output,
    645      * null ignored
    646      * @param output  the <code>Writer</code> to write to
    647      * @throws NullPointerException if output is null
    648      * @throws IOException if an I/O error occurs
    649      * @since Commons IO 1.1
    650      */
    651     public static void write(byte[] data, Writer output) throws IOException {
    652         if (data != null) {
    653             output.write(new String(data));
    654         }
    655     }
    656 
    657     /**
    658      * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code>
    659      * using the specified character encoding.
    660      * <p>
    661      * Character encoding names can be found at
    662      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    663      * <p>
    664      * This method uses {@link String#String(byte[], String)}.
    665      *
    666      * @param data  the byte array to write, do not modify during output,
    667      * null ignored
    668      * @param output  the <code>Writer</code> to write to
    669      * @param encoding  the encoding to use, null means platform default
    670      * @throws NullPointerException if output is null
    671      * @throws IOException if an I/O error occurs
    672      * @since Commons IO 1.1
    673      */
    674     public static void write(byte[] data, Writer output, String encoding)
    675             throws IOException {
    676         if (data != null) {
    677             if (encoding == null) {
    678                 write(data, output);
    679             } else {
    680                 output.write(new String(data, encoding));
    681             }
    682         }
    683     }
    684 
    685     // write char[]
    686     //-----------------------------------------------------------------------
    687     /**
    688      * Writes chars from a <code>char[]</code> to a <code>Writer</code>
    689      * using the default character encoding of the platform.
    690      *
    691      * @param data  the char array to write, do not modify during output,
    692      * null ignored
    693      * @param output  the <code>Writer</code> to write to
    694      * @throws NullPointerException if output is null
    695      * @throws IOException if an I/O error occurs
    696      * @since Commons IO 1.1
    697      */
    698     public static void write(char[] data, Writer output) throws IOException {
    699         if (data != null) {
    700             output.write(data);
    701         }
    702     }
    703 
    704     /**
    705      * Writes chars from a <code>char[]</code> to bytes on an
    706      * <code>OutputStream</code>.
    707      * <p>
    708      * This method uses {@link String#String(char[])} and
    709      * {@link String#getBytes()}.
    710      *
    711      * @param data  the char array to write, do not modify during output,
    712      * null ignored
    713      * @param output  the <code>OutputStream</code> to write to
    714      * @throws NullPointerException if output is null
    715      * @throws IOException if an I/O error occurs
    716      * @since Commons IO 1.1
    717      */
    718     public static void write(char[] data, OutputStream output)
    719             throws IOException {
    720         if (data != null) {
    721             output.write(new String(data).getBytes());
    722         }
    723     }
    724 
    725     /**
    726      * Writes chars from a <code>char[]</code> to bytes on an
    727      * <code>OutputStream</code> using the specified character encoding.
    728      * <p>
    729      * Character encoding names can be found at
    730      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    731      * <p>
    732      * This method uses {@link String#String(char[])} and
    733      * {@link String#getBytes(String)}.
    734      *
    735      * @param data  the char array to write, do not modify during output,
    736      * null ignored
    737      * @param output  the <code>OutputStream</code> to write to
    738      * @param encoding  the encoding to use, null means platform default
    739      * @throws NullPointerException if output is null
    740      * @throws IOException if an I/O error occurs
    741      * @since Commons IO 1.1
    742      */
    743     public static void write(char[] data, OutputStream output, String encoding)
    744             throws IOException {
    745         if (data != null) {
    746             if (encoding == null) {
    747                 write(data, output);
    748             } else {
    749                 output.write(new String(data).getBytes(encoding));
    750             }
    751         }
    752     }
    753 
    754     // write String
    755     //-----------------------------------------------------------------------
    756     /**
    757      * Writes chars from a <code>String</code> to a <code>Writer</code>.
    758      *
    759      * @param data  the <code>String</code> to write, null ignored
    760      * @param output  the <code>Writer</code> to write to
    761      * @throws NullPointerException if output is null
    762      * @throws IOException if an I/O error occurs
    763      * @since Commons IO 1.1
    764      */
    765     public static void write(String data, Writer output) throws IOException {
    766         if (data != null) {
    767             output.write(data);
    768         }
    769     }
    770 
    771     /**
    772      * Writes chars from a <code>String</code> to bytes on an
    773      * <code>OutputStream</code> using the default character encoding of the
    774      * platform.
    775      * <p>
    776      * This method uses {@link String#getBytes()}.
    777      *
    778      * @param data  the <code>String</code> to write, null ignored
    779      * @param output  the <code>OutputStream</code> to write to
    780      * @throws NullPointerException if output is null
    781      * @throws IOException if an I/O error occurs
    782      * @since Commons IO 1.1
    783      */
    784     public static void write(String data, OutputStream output)
    785             throws IOException {
    786         if (data != null) {
    787             output.write(data.getBytes());
    788         }
    789     }
    790 
    791     /**
    792      * Writes chars from a <code>String</code> to bytes on an
    793      * <code>OutputStream</code> using the specified character encoding.
    794      * <p>
    795      * Character encoding names can be found at
    796      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    797      * <p>
    798      * This method uses {@link String#getBytes(String)}.
    799      *
    800      * @param data  the <code>String</code> to write, null ignored
    801      * @param output  the <code>OutputStream</code> to write to
    802      * @param encoding  the encoding to use, null means platform default
    803      * @throws NullPointerException if output is null
    804      * @throws IOException if an I/O error occurs
    805      * @since Commons IO 1.1
    806      */
    807     public static void write(String data, OutputStream output, String encoding)
    808             throws IOException {
    809         if (data != null) {
    810             if (encoding == null) {
    811                 write(data, output);
    812             } else {
    813                 output.write(data.getBytes(encoding));
    814             }
    815         }
    816     }
    817 
    818     // write StringBuffer
    819     //-----------------------------------------------------------------------
    820     /**
    821      * Writes chars from a <code>StringBuffer</code> to a <code>Writer</code>.
    822      *
    823      * @param data  the <code>StringBuffer</code> to write, null ignored
    824      * @param output  the <code>Writer</code> to write to
    825      * @throws NullPointerException if output is null
    826      * @throws IOException if an I/O error occurs
    827      * @since Commons IO 1.1
    828      */
    829     public static void write(StringBuffer data, Writer output)
    830             throws IOException {
    831         if (data != null) {
    832             output.write(data.toString());
    833         }
    834     }
    835 
    836     /**
    837      * Writes chars from a <code>StringBuffer</code> to bytes on an
    838      * <code>OutputStream</code> using the default character encoding of the
    839      * platform.
    840      * <p>
    841      * This method uses {@link String#getBytes()}.
    842      *
    843      * @param data  the <code>StringBuffer</code> to write, null ignored
    844      * @param output  the <code>OutputStream</code> to write to
    845      * @throws NullPointerException if output is null
    846      * @throws IOException if an I/O error occurs
    847      * @since Commons IO 1.1
    848      */
    849     public static void write(StringBuffer data, OutputStream output)
    850             throws IOException {
    851         if (data != null) {
    852             output.write(data.toString().getBytes());
    853         }
    854     }
    855 
    856     /**
    857      * Writes chars from a <code>StringBuffer</code> to bytes on an
    858      * <code>OutputStream</code> using the specified character encoding.
    859      * <p>
    860      * Character encoding names can be found at
    861      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    862      * <p>
    863      * This method uses {@link String#getBytes(String)}.
    864      *
    865      * @param data  the <code>StringBuffer</code> to write, null ignored
    866      * @param output  the <code>OutputStream</code> to write to
    867      * @param encoding  the encoding to use, null means platform default
    868      * @throws NullPointerException if output is null
    869      * @throws IOException if an I/O error occurs
    870      * @since Commons IO 1.1
    871      */
    872     public static void write(StringBuffer data, OutputStream output,
    873             String encoding) throws IOException {
    874         if (data != null) {
    875             if (encoding == null) {
    876                 write(data, output);
    877             } else {
    878                 output.write(data.toString().getBytes(encoding));
    879             }
    880         }
    881     }
    882 
    883     // writeLines
    884     //-----------------------------------------------------------------------
    885     /**
    886      * Writes the <code>toString()</code> value of each item in a collection to
    887      * an <code>OutputStream</code> line by line, using the default character
    888      * encoding of the platform and the specified line ending.
    889      *
    890      * @param lines  the lines to write, null entries produce blank lines
    891      * @param lineEnding  the line separator to use, null is system default
    892      * @param output  the <code>OutputStream</code> to write to, not null, not closed
    893      * @throws NullPointerException if the output is null
    894      * @throws IOException if an I/O error occurs
    895      * @since Commons IO 1.1
    896      */
    897     public static void writeLines(Collection<Object> lines, String lineEnding,
    898             OutputStream output) throws IOException {
    899         if (lines == null) {
    900             return;
    901         }
    902         if (lineEnding == null) {
    903             lineEnding = LINE_SEPARATOR;
    904         }
    905         for (Iterator<Object> it = lines.iterator(); it.hasNext(); ) {
    906             Object line = it.next();
    907             if (line != null) {
    908                 output.write(line.toString().getBytes());
    909             }
    910             output.write(lineEnding.getBytes());
    911         }
    912     }
    913 
    914     /**
    915      * Writes the <code>toString()</code> value of each item in a collection to
    916      * an <code>OutputStream</code> line by line, using the specified character
    917      * encoding and the specified line ending.
    918      * <p>
    919      * Character encoding names can be found at
    920      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
    921      *
    922      * @param lines  the lines to write, null entries produce blank lines
    923      * @param lineEnding  the line separator to use, null is system default
    924      * @param output  the <code>OutputStream</code> to write to, not null, not closed
    925      * @param encoding  the encoding to use, null means platform default
    926      * @throws NullPointerException if the output is null
    927      * @throws IOException if an I/O error occurs
    928      * @since Commons IO 1.1
    929      */
    930     public static void writeLines(Collection<Object> lines, String lineEnding,
    931             OutputStream output, String encoding) throws IOException {
    932         if (encoding == null) {
    933             writeLines(lines, lineEnding, output);
    934         } else {
    935             if (lines == null) {
    936                 return;
    937             }
    938             if (lineEnding == null) {
    939                 lineEnding = LINE_SEPARATOR;
    940             }
    941             for (Iterator<Object> it = lines.iterator(); it.hasNext(); ) {
    942                 Object line = it.next();
    943                 if (line != null) {
    944                     output.write(line.toString().getBytes(encoding));
    945                 }
    946                 output.write(lineEnding.getBytes(encoding));
    947             }
    948         }
    949     }
    950 
    951     /**
    952      * Writes the <code>toString()</code> value of each item in a collection to
    953      * a <code>Writer</code> line by line, using the specified line ending.
    954      *
    955      * @param lines  the lines to write, null entries produce blank lines
    956      * @param lineEnding  the line separator to use, null is system default
    957      * @param writer  the <code>Writer</code> to write to, not null, not closed
    958      * @throws NullPointerException if the input is null
    959      * @throws IOException if an I/O error occurs
    960      * @since Commons IO 1.1
    961      */
    962     public static void writeLines(Collection<Object> lines, String lineEnding,
    963             Writer writer) throws IOException {
    964         if (lines == null) {
    965             return;
    966         }
    967         if (lineEnding == null) {
    968             lineEnding = LINE_SEPARATOR;
    969         }
    970         for (Iterator<Object> it = lines.iterator(); it.hasNext(); ) {
    971             Object line = it.next();
    972             if (line != null) {
    973                 writer.write(line.toString());
    974             }
    975             writer.write(lineEnding);
    976         }
    977     }
    978 
    979     // copy from InputStream
    980     //-----------------------------------------------------------------------
    981     /**
    982      * Copy bytes from an <code>InputStream</code> to an
    983      * <code>OutputStream</code>.
    984      * <p>
    985      * This method buffers the input internally, so there is no need to use a
    986      * <code>BufferedInputStream</code>.
    987      * <p>
    988      * Large streams (over 2GB) will return a bytes copied value of
    989      * <code>-1</code> after the copy has completed since the correct
    990      * number of bytes cannot be returned as an int. For large streams
    991      * use the <code>copyLarge(InputStream, OutputStream)</code> method.
    992      *
    993      * @param input  the <code>InputStream</code> to read from
    994      * @param output  the <code>OutputStream</code> to write to
    995      * @return the number of bytes copied
    996      * @throws NullPointerException if the input or output is null
    997      * @throws IOException if an I/O error occurs
    998      * @throws ArithmeticException if the byte count is too large
    999      * @since Commons IO 1.1
   1000      */
   1001     public static int copy(InputStream input, OutputStream output) throws IOException {
   1002         long count = copyLarge(input, output);
   1003         if (count > Integer.MAX_VALUE) {
   1004             return -1;
   1005         }
   1006         return (int) count;
   1007     }
   1008 
   1009     /**
   1010      * Copy bytes from a large (over 2GB) <code>InputStream</code> to an
   1011      * <code>OutputStream</code>.
   1012      * <p>
   1013      * This method buffers the input internally, so there is no need to use a
   1014      * <code>BufferedInputStream</code>.
   1015      *
   1016      * @param input  the <code>InputStream</code> to read from
   1017      * @param output  the <code>OutputStream</code> to write to
   1018      * @return the number of bytes copied
   1019      * @throws NullPointerException if the input or output is null
   1020      * @throws IOException if an I/O error occurs
   1021      * @since Commons IO 1.3
   1022      */
   1023     public static long copyLarge(InputStream input, OutputStream output)
   1024             throws IOException {
   1025         byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
   1026         long count = 0;
   1027         int n = 0;
   1028         while (-1 != (n = input.read(buffer))) {
   1029             output.write(buffer, 0, n);
   1030             count += n;
   1031         }
   1032         return count;
   1033     }
   1034 
   1035     /**
   1036      * Copy bytes from an <code>InputStream</code> to chars on a
   1037      * <code>Writer</code> using the default character encoding of the platform.
   1038      * <p>
   1039      * This method buffers the input internally, so there is no need to use a
   1040      * <code>BufferedInputStream</code>.
   1041      * <p>
   1042      * This method uses {@link InputStreamReader}.
   1043      *
   1044      * @param input  the <code>InputStream</code> to read from
   1045      * @param output  the <code>Writer</code> to write to
   1046      * @throws NullPointerException if the input or output is null
   1047      * @throws IOException if an I/O error occurs
   1048      * @since Commons IO 1.1
   1049      */
   1050     public static void copy(InputStream input, Writer output)
   1051             throws IOException {
   1052         InputStreamReader in = new InputStreamReader(input);
   1053         copy(in, output);
   1054     }
   1055 
   1056     /**
   1057      * Copy bytes from an <code>InputStream</code> to chars on a
   1058      * <code>Writer</code> using the specified character encoding.
   1059      * <p>
   1060      * This method buffers the input internally, so there is no need to use a
   1061      * <code>BufferedInputStream</code>.
   1062      * <p>
   1063      * Character encoding names can be found at
   1064      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
   1065      * <p>
   1066      * This method uses {@link InputStreamReader}.
   1067      *
   1068      * @param input  the <code>InputStream</code> to read from
   1069      * @param output  the <code>Writer</code> to write to
   1070      * @param encoding  the encoding to use, null means platform default
   1071      * @throws NullPointerException if the input or output is null
   1072      * @throws IOException if an I/O error occurs
   1073      * @since Commons IO 1.1
   1074      */
   1075     public static void copy(InputStream input, Writer output, String encoding)
   1076             throws IOException {
   1077         if (encoding == null) {
   1078             copy(input, output);
   1079         } else {
   1080             InputStreamReader in = new InputStreamReader(input, encoding);
   1081             copy(in, output);
   1082         }
   1083     }
   1084 
   1085     // copy from Reader
   1086     //-----------------------------------------------------------------------
   1087     /**
   1088      * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
   1089      * <p>
   1090      * This method buffers the input internally, so there is no need to use a
   1091      * <code>BufferedReader</code>.
   1092      * <p>
   1093      * Large streams (over 2GB) will return a chars copied value of
   1094      * <code>-1</code> after the copy has completed since the correct
   1095      * number of chars cannot be returned as an int. For large streams
   1096      * use the <code>copyLarge(Reader, Writer)</code> method.
   1097      *
   1098      * @param input  the <code>Reader</code> to read from
   1099      * @param output  the <code>Writer</code> to write to
   1100      * @return the number of characters copied
   1101      * @throws NullPointerException if the input or output is null
   1102      * @throws IOException if an I/O error occurs
   1103      * @throws ArithmeticException if the character count is too large
   1104      * @since Commons IO 1.1
   1105      */
   1106     public static int copy(Reader input, Writer output) throws IOException {
   1107         long count = copyLarge(input, output);
   1108         if (count > Integer.MAX_VALUE) {
   1109             return -1;
   1110         }
   1111         return (int) count;
   1112     }
   1113 
   1114     /**
   1115      * Copy chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>.
   1116      * <p>
   1117      * This method buffers the input internally, so there is no need to use a
   1118      * <code>BufferedReader</code>.
   1119      *
   1120      * @param input  the <code>Reader</code> to read from
   1121      * @param output  the <code>Writer</code> to write to
   1122      * @return the number of characters copied
   1123      * @throws NullPointerException if the input or output is null
   1124      * @throws IOException if an I/O error occurs
   1125      * @since Commons IO 1.3
   1126      */
   1127     public static long copyLarge(Reader input, Writer output) throws IOException {
   1128         char[] buffer = new char[DEFAULT_BUFFER_SIZE];
   1129         long count = 0;
   1130         int n = 0;
   1131         while (-1 != (n = input.read(buffer))) {
   1132             output.write(buffer, 0, n);
   1133             count += n;
   1134         }
   1135         return count;
   1136     }
   1137 
   1138     /**
   1139      * Copy chars from a <code>Reader</code> to bytes on an
   1140      * <code>OutputStream</code> using the default character encoding of the
   1141      * platform, and calling flush.
   1142      * <p>
   1143      * This method buffers the input internally, so there is no need to use a
   1144      * <code>BufferedReader</code>.
   1145      * <p>
   1146      * Due to the implementation of OutputStreamWriter, this method performs a
   1147      * flush.
   1148      * <p>
   1149      * This method uses {@link OutputStreamWriter}.
   1150      *
   1151      * @param input  the <code>Reader</code> to read from
   1152      * @param output  the <code>OutputStream</code> to write to
   1153      * @throws NullPointerException if the input or output is null
   1154      * @throws IOException if an I/O error occurs
   1155      * @since Commons IO 1.1
   1156      */
   1157     public static void copy(Reader input, OutputStream output)
   1158             throws IOException {
   1159         OutputStreamWriter out = new OutputStreamWriter(output);
   1160         copy(input, out);
   1161         // XXX Unless anyone is planning on rewriting OutputStreamWriter, we
   1162         // have to flush here.
   1163         out.flush();
   1164     }
   1165 
   1166     /**
   1167      * Copy chars from a <code>Reader</code> to bytes on an
   1168      * <code>OutputStream</code> using the specified character encoding, and
   1169      * calling flush.
   1170      * <p>
   1171      * This method buffers the input internally, so there is no need to use a
   1172      * <code>BufferedReader</code>.
   1173      * <p>
   1174      * Character encoding names can be found at
   1175      * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
   1176      * <p>
   1177      * Due to the implementation of OutputStreamWriter, this method performs a
   1178      * flush.
   1179      * <p>
   1180      * This method uses {@link OutputStreamWriter}.
   1181      *
   1182      * @param input  the <code>Reader</code> to read from
   1183      * @param output  the <code>OutputStream</code> to write to
   1184      * @param encoding  the encoding to use, null means platform default
   1185      * @throws NullPointerException if the input or output is null
   1186      * @throws IOException if an I/O error occurs
   1187      * @since Commons IO 1.1
   1188      */
   1189     public static void copy(Reader input, OutputStream output, String encoding)
   1190             throws IOException {
   1191         if (encoding == null) {
   1192             copy(input, output);
   1193         } else {
   1194             OutputStreamWriter out = new OutputStreamWriter(output, encoding);
   1195             copy(input, out);
   1196             // XXX Unless anyone is planning on rewriting OutputStreamWriter,
   1197             // we have to flush here.
   1198             out.flush();
   1199         }
   1200     }
   1201 
   1202     // content equals
   1203     //-----------------------------------------------------------------------
   1204     /**
   1205      * Compare the contents of two Streams to determine if they are equal or
   1206      * not.
   1207      * <p>
   1208      * This method buffers the input internally using
   1209      * <code>BufferedInputStream</code> if they are not already buffered.
   1210      *
   1211      * @param input1  the first stream
   1212      * @param input2  the second stream
   1213      * @return true if the content of the streams are equal or they both don't
   1214      * exist, false otherwise
   1215      * @throws NullPointerException if either input is null
   1216      * @throws IOException if an I/O error occurs
   1217      */
   1218     public static boolean contentEquals(InputStream input1, InputStream input2)
   1219             throws IOException {
   1220         if (!(input1 instanceof BufferedInputStream)) {
   1221             input1 = new BufferedInputStream(input1);
   1222         }
   1223         if (!(input2 instanceof BufferedInputStream)) {
   1224             input2 = new BufferedInputStream(input2);
   1225         }
   1226 
   1227         int ch = input1.read();
   1228         while (-1 != ch) {
   1229             int ch2 = input2.read();
   1230             if (ch != ch2) {
   1231                 return false;
   1232             }
   1233             ch = input1.read();
   1234         }
   1235 
   1236         int ch2 = input2.read();
   1237         return (ch2 == -1);
   1238     }
   1239 
   1240     /**
   1241      * Compare the contents of two Readers to determine if they are equal or
   1242      * not.
   1243      * <p>
   1244      * This method buffers the input internally using
   1245      * <code>BufferedReader</code> if they are not already buffered.
   1246      *
   1247      * @param input1  the first reader
   1248      * @param input2  the second reader
   1249      * @return true if the content of the readers are equal or they both don't
   1250      * exist, false otherwise
   1251      * @throws NullPointerException if either input is null
   1252      * @throws IOException if an I/O error occurs
   1253      * @since Commons IO 1.1
   1254      */
   1255     public static boolean contentEquals(Reader input1, Reader input2)
   1256             throws IOException {
   1257         if (!(input1 instanceof BufferedReader)) {
   1258             input1 = new BufferedReader(input1);
   1259         }
   1260         if (!(input2 instanceof BufferedReader)) {
   1261             input2 = new BufferedReader(input2);
   1262         }
   1263 
   1264         int ch = input1.read();
   1265         while (-1 != ch) {
   1266             int ch2 = input2.read();
   1267             if (ch != ch2) {
   1268                 return false;
   1269             }
   1270             ch = input1.read();
   1271         }
   1272 
   1273         int ch2 = input2.read();
   1274         return (ch2 == -1);
   1275     }
   1276 
   1277 }
   1278