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