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