View Javadoc

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