001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     * 
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.io;
018    
019    import java.io.BufferedInputStream;
020    import java.io.BufferedReader;
021    import java.io.ByteArrayInputStream;
022    import java.io.CharArrayWriter;
023    import java.io.Closeable;
024    import java.io.EOFException;
025    import java.io.File;
026    import java.io.IOException;
027    import java.io.InputStream;
028    import java.io.InputStreamReader;
029    import java.io.OutputStream;
030    import java.io.OutputStreamWriter;
031    import java.io.PrintWriter;
032    import java.io.Reader;
033    import java.io.UnsupportedEncodingException;
034    import java.io.Writer;
035    import java.net.ServerSocket;
036    import java.net.Socket;
037    import java.net.URI;
038    import java.net.URL;
039    import java.nio.channels.Selector;
040    import java.nio.charset.Charset;
041    import java.nio.charset.UnsupportedCharsetException;
042    import java.util.ArrayList;
043    import java.util.Collection;
044    import java.util.List;
045    
046    import org.apache.commons.io.output.ByteArrayOutputStream;
047    import org.apache.commons.io.output.StringBuilderWriter;
048    
049    /**
050     * General IO stream manipulation utilities.
051     * <p>
052     * This class provides static utility methods for input/output operations.
053     * <ul>
054     * <li>closeQuietly - these methods close a stream ignoring nulls and exceptions
055     * <li>toXxx/read - these methods read data from a stream
056     * <li>write - these methods write data to a stream
057     * <li>copy - these methods copy all the data from one stream to another
058     * <li>contentEquals - these methods compare the content of two streams
059     * </ul>
060     * <p>
061     * The byte-to-char methods and char-to-byte methods involve a conversion step.
062     * Two methods are provided in each case, one that uses the platform default
063     * encoding and the other which allows you to specify an encoding. You are
064     * encouraged to always specify an encoding because relying on the platform
065     * default can lead to unexpected results, for example when moving from
066     * development to production.
067     * <p>
068     * All the methods in this class that read a stream are buffered internally.
069     * This means that there is no cause to use a <code>BufferedInputStream</code>
070     * or <code>BufferedReader</code>. The default buffer size of 4K has been shown
071     * to be efficient in tests.
072     * <p>
073     * Wherever possible, the methods in this class do <em>not</em> flush or close
074     * the stream. This is to avoid making non-portable assumptions about the
075     * streams' origin and further use. Thus the caller is still responsible for
076     * closing streams after use.
077     * <p>
078     * Origin of code: Excalibur.
079     *
080     * @version $Id: IOUtils.java 1307412 2012-03-30 13:40:31Z ggregory $
081     */
082    public class IOUtils {
083        // NOTE: This class is focussed on InputStream, OutputStream, Reader and
084        // Writer. Each method should take at least one of these as a parameter,
085        // or return one of them.
086    
087        private static final int EOF = -1;
088        /**
089         * The Unix directory separator character.
090         */
091        public static final char DIR_SEPARATOR_UNIX = '/';
092        /**
093         * The Windows directory separator character.
094         */
095        public static final char DIR_SEPARATOR_WINDOWS = '\\';
096        /**
097         * The system directory separator character.
098         */
099        public static final char DIR_SEPARATOR = File.separatorChar;
100        /**
101         * The Unix line separator string.
102         */
103        public static final String LINE_SEPARATOR_UNIX = "\n";
104        /**
105         * The Windows line separator string.
106         */
107        public static final String LINE_SEPARATOR_WINDOWS = "\r\n";
108        /**
109         * The system line separator string.
110         */
111        public static final String LINE_SEPARATOR;
112        
113        static {
114            // avoid security issues
115            StringBuilderWriter buf = new StringBuilderWriter(4);
116            PrintWriter out = new PrintWriter(buf);
117            out.println();
118            LINE_SEPARATOR = buf.toString();
119            out.close();
120        }
121    
122        /**
123         * The default buffer size ({@value}) to use for 
124         * {@link #copyLarge(InputStream, OutputStream)}
125         * and
126         * {@link #copyLarge(Reader, Writer)}
127         */
128        private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
129    
130        /**
131         * The default buffer size to use for the skip() methods.
132         */
133        private static final int SKIP_BUFFER_SIZE = 2048;
134        
135        // Allocated in the relevant skip method if necessary.
136        /*
137         * N.B. no need to synchronize these because:
138         * - we don't care if the buffer is created multiple times (the data is ignored)
139         * - we always use the same size buffer, so if it it is recreated it will still be OK
140         * (if the buffer size were variable, we would need to synch. to ensure some other thread
141         * did not create a smaller one)
142         */
143        private static char[] SKIP_CHAR_BUFFER;
144        private static byte[] SKIP_BYTE_BUFFER;
145    
146        /**
147         * Instances should NOT be constructed in standard programming.
148         */
149        public IOUtils() {
150            super();
151        }
152    
153        //-----------------------------------------------------------------------
154        /**
155         * Unconditionally close an <code>Reader</code>.
156         * <p>
157         * Equivalent to {@link Reader#close()}, except any exceptions will be ignored.
158         * This is typically used in finally blocks.
159         * <p>
160         * Example code:
161         * <pre>
162         *   char[] data = new char[1024];
163         *   Reader in = null;
164         *   try {
165         *       in = new FileReader("foo.txt");
166         *       in.read(data);
167         *       in.close(); //close errors are handled
168         *   } catch (Exception e) {
169         *       // error handling
170         *   } finally {
171         *       IOUtils.closeQuietly(in);
172         *   }
173         * </pre>
174         * 
175         * @param input  the Reader to close, may be null or already closed
176         */
177        public static void closeQuietly(Reader input) {
178            closeQuietly((Closeable)input);
179        }
180    
181        /**
182         * Unconditionally close a <code>Writer</code>.
183         * <p>
184         * Equivalent to {@link Writer#close()}, except any exceptions will be ignored.
185         * This is typically used in finally blocks.
186         * <p>
187         * Example code:
188         * <pre>
189         *   Writer out = null;
190         *   try {
191         *       out = new StringWriter();
192         *       out.write("Hello World");
193         *       out.close(); //close errors are handled
194         *   } catch (Exception e) {
195         *       // error handling
196         *   } finally {
197         *       IOUtils.closeQuietly(out);
198         *   }
199         * </pre>
200         *
201         * @param output  the Writer to close, may be null or already closed
202         */
203        public static void closeQuietly(Writer output) {
204            closeQuietly((Closeable)output);
205        }
206    
207        /**
208         * Unconditionally close an <code>InputStream</code>.
209         * <p>
210         * Equivalent to {@link InputStream#close()}, except any exceptions will be ignored.
211         * This is typically used in finally blocks.
212         * <p>
213         * Example code:
214         * <pre>
215         *   byte[] data = new byte[1024];
216         *   InputStream in = null;
217         *   try {
218         *       in = new FileInputStream("foo.txt");
219         *       in.read(data);
220         *       in.close(); //close errors are handled
221         *   } catch (Exception e) {
222         *       // error handling
223         *   } finally {
224         *       IOUtils.closeQuietly(in);
225         *   }
226         * </pre>
227         *
228         * @param input  the InputStream to close, may be null or already closed
229         */
230        public static void closeQuietly(InputStream input) {
231            closeQuietly((Closeable)input);
232        }
233    
234        /**
235         * Unconditionally close an <code>OutputStream</code>.
236         * <p>
237         * Equivalent to {@link OutputStream#close()}, except any exceptions will be ignored.
238         * This is typically used in finally blocks.
239         * <p>
240         * Example code:
241         * <pre>
242         * byte[] data = "Hello, World".getBytes();
243         *
244         * OutputStream out = null;
245         * try {
246         *     out = new FileOutputStream("foo.txt");
247         *     out.write(data);
248         *     out.close(); //close errors are handled
249         * } catch (IOException e) {
250         *     // error handling
251         * } finally {
252         *     IOUtils.closeQuietly(out);
253         * }
254         * </pre>
255         *
256         * @param output  the OutputStream to close, may be null or already closed
257         */
258        public static void closeQuietly(OutputStream output) {
259            closeQuietly((Closeable)output);
260        }
261        
262        /**
263         * Unconditionally close a <code>Closeable</code>.
264         * <p>
265         * Equivalent to {@link Closeable#close()}, except any exceptions will be ignored.
266         * This is typically used in finally blocks.
267         * <p>
268         * Example code:
269         * <pre>
270         *   Closeable closeable = null;
271         *   try {
272         *       closeable = new FileReader("foo.txt");
273         *       // process closeable
274         *       closeable.close();
275         *   } catch (Exception e) {
276         *       // error handling
277         *   } finally {
278         *       IOUtils.closeQuietly(closeable);
279         *   }
280         * </pre>
281         *
282         * @param closeable the object to close, may be null or already closed
283         * @since 2.0
284         */
285        public static void closeQuietly(Closeable closeable) {
286            try {
287                if (closeable != null) {
288                    closeable.close();
289                }
290            } catch (IOException ioe) {
291                // ignore
292            }
293        }
294    
295        /**
296         * Unconditionally close a <code>Socket</code>.
297         * <p>
298         * Equivalent to {@link Socket#close()}, except any exceptions will be ignored.
299         * This is typically used in finally blocks.
300         * <p>
301         * Example code:
302         * <pre>
303         *   Socket socket = null;
304         *   try {
305         *       socket = new Socket("http://www.foo.com/", 80);
306         *       // process socket
307         *       socket.close();
308         *   } catch (Exception e) {
309         *       // error handling
310         *   } finally {
311         *       IOUtils.closeQuietly(socket);
312         *   }
313         * </pre>
314         *
315         * @param sock the Socket to close, may be null or already closed
316         * @since 2.0
317         */
318        public static void closeQuietly(Socket sock){
319            if (sock != null){
320                try {
321                    sock.close();
322                } catch (IOException ioe) {
323                    // ignored
324                }
325            }
326        }
327    
328        /**
329         * Unconditionally close a <code>Selector</code>.
330         * <p>
331         * Equivalent to {@link Selector#close()}, except any exceptions will be ignored.
332         * This is typically used in finally blocks.
333         * <p>
334         * Example code:
335         * <pre>
336         *   Selector selector = null;
337         *   try {
338         *       selector = Selector.open();
339         *       // process socket
340         *       
341         *   } catch (Exception e) {
342         *       // error handling
343         *   } finally {
344         *       IOUtils.closeQuietly(selector);
345         *   }
346         * </pre>
347         *
348         * @param selector the Selector to close, may be null or already closed
349         * @since 2.2
350         */
351        public static void closeQuietly(Selector selector){
352            if (selector != null){
353                try {
354                  selector.close();
355                } catch (IOException ioe) {
356                    // ignored
357                }
358            }
359        }
360        
361        /**
362         * Unconditionally close a <code>ServerSocket</code>.
363         * <p>
364         * Equivalent to {@link ServerSocket#close()}, except any exceptions will be ignored.
365         * This is typically used in finally blocks.
366         * <p>
367         * Example code:
368         * <pre>
369         *   ServerSocket socket = null;
370         *   try {
371         *       socket = new ServerSocket();
372         *       // process socket
373         *       socket.close();
374         *   } catch (Exception e) {
375         *       // error handling
376         *   } finally {
377         *       IOUtils.closeQuietly(socket);
378         *   }
379         * </pre>
380         *
381         * @param sock the ServerSocket to close, may be null or already closed
382         * @since 2.2
383         */
384        public static void closeQuietly(ServerSocket sock){
385            if (sock != null){
386                try {
387                    sock.close();
388                } catch (IOException ioe) {
389                    // ignored
390                }
391            }
392        }
393    
394        /**
395         * Fetches entire contents of an <code>InputStream</code> and represent
396         * same data as result InputStream.
397         * <p>
398         * This method is useful where,
399         * <ul>
400         * <li>Source InputStream is slow.</li>
401         * <li>It has network resources associated, so we cannot keep it open for
402         * long time.</li>
403         * <li>It has network timeout associated.</li>
404         * </ul>
405         * It can be used in favor of {@link #toByteArray(InputStream)}, since it
406         * avoids unnecessary allocation and copy of byte[].<br>
407         * This method buffers the input internally, so there is no need to use a
408         * <code>BufferedInputStream</code>.
409         * 
410         * @param input Stream to be fully buffered.
411         * @return A fully buffered stream.
412         * @throws IOException if an I/O error occurs
413         * @since 2.0
414         */
415        public static InputStream toBufferedInputStream(InputStream input) throws IOException {
416            return ByteArrayOutputStream.toBufferedInputStream(input);
417        }
418    
419        /**
420         * Returns the given reader if it is a {@link BufferedReader}, otherwise creates a toBufferedReader for the given
421         * reader.
422         * 
423         * @param reader
424         *            the reader to wrap or return
425         * @return the given reader or a new {@link BufferedReader} for the given reader
426         * @since 2.2
427         */
428        public static BufferedReader toBufferedReader(Reader reader) {
429            return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader);
430        }
431        
432        // read toByteArray
433        //-----------------------------------------------------------------------
434        /**
435         * Get the contents of an <code>InputStream</code> as a <code>byte[]</code>.
436         * <p>
437         * This method buffers the input internally, so there is no need to use a
438         * <code>BufferedInputStream</code>.
439         * 
440         * @param input  the <code>InputStream</code> to read from
441         * @return the requested byte array
442         * @throws NullPointerException if the input is null
443         * @throws IOException if an I/O error occurs
444         */
445        public static byte[] toByteArray(InputStream input) throws IOException {
446            ByteArrayOutputStream output = new ByteArrayOutputStream();
447            copy(input, output);
448            return output.toByteArray();
449        }
450    
451        /**
452         * Get contents of an <code>InputStream</code> as a <code>byte[]</code>.
453         * Use this method instead of <code>toByteArray(InputStream)</code>
454         * when <code>InputStream</code> size is known.
455         * <b>NOTE:</b> the method checks that the length can safely be cast to an int without truncation
456         * before using {@link IOUtils#toByteArray(java.io.InputStream, int)} to read into the byte array.
457         * (Arrays can have no more than Integer.MAX_VALUE entries anyway)
458         * 
459         * @param input the <code>InputStream</code> to read from
460         * @param size the size of <code>InputStream</code>
461         * @return the requested byte array
462         * @throws IOException if an I/O error occurs or <code>InputStream</code> size differ from parameter size
463         * @throws IllegalArgumentException if size is less than zero or size is greater than Integer.MAX_VALUE
464         * @see IOUtils#toByteArray(java.io.InputStream, int)
465         * @since 2.1
466         */
467        public static byte[] toByteArray(InputStream input, long size) throws IOException {
468    
469          if(size > Integer.MAX_VALUE) {
470              throw new IllegalArgumentException("Size cannot be greater than Integer max value: " + size);
471          }
472    
473          return toByteArray(input, (int) size);
474        }
475    
476        /** 
477         * Get the contents of an <code>InputStream</code> as a <code>byte[]</code>.
478         * Use this method instead of <code>toByteArray(InputStream)</code>
479         * when <code>InputStream</code> size is known
480         * @param input the <code>InputStream</code> to read from
481         * @param size the size of <code>InputStream</code>
482         * @return the requested byte array
483         * @throws IOException if an I/O error occurs or <code>InputStream</code> size differ from parameter size
484         * @throws IllegalArgumentException if size is less than zero
485         * @since 2.1
486         */
487        public static byte[] toByteArray(InputStream input, int size) throws IOException {
488    
489            if (size < 0) {
490                throw new IllegalArgumentException("Size must be equal or greater than zero: " + size);
491            }
492    
493            if (size == 0) {
494                return new byte[0];
495            }
496    
497            byte[] data = new byte[size];
498            int offset = 0;
499            int readed;
500    
501            while (offset < size && (readed = input.read(data, offset, size - offset)) != EOF) {
502                offset += readed;
503            }
504    
505            if (offset != size) {
506                throw new IOException("Unexpected readed size. current: " + offset + ", excepted: " + size);
507            }
508    
509            return data;
510        }
511    
512        /**
513         * Get the contents of a <code>Reader</code> as a <code>byte[]</code>
514         * using the default character encoding of the platform.
515         * <p>
516         * This method buffers the input internally, so there is no need to use a
517         * <code>BufferedReader</code>.
518         * 
519         * @param input  the <code>Reader</code> to read from
520         * @return the requested byte array
521         * @throws NullPointerException if the input is null
522         * @throws IOException if an I/O error occurs
523         */
524        public static byte[] toByteArray(Reader input) throws IOException {
525            return toByteArray(input, Charset.defaultCharset());
526        }
527    
528        /**
529         * Get the contents of a <code>Reader</code> as a <code>byte[]</code>
530         * using the specified character encoding.
531         * <p>
532         * This method buffers the input internally, so there is no need to use a
533         * <code>BufferedReader</code>.
534         * 
535         * @param input  the <code>Reader</code> to read from
536         * @param encoding  the encoding to use, null means platform default
537         * @return the requested byte array
538         * @throws NullPointerException if the input is null
539         * @throws IOException if an I/O error occurs
540         * @since 2.3
541         */
542        public static byte[] toByteArray(Reader input, Charset encoding) throws IOException {
543            ByteArrayOutputStream output = new ByteArrayOutputStream();
544            copy(input, output, encoding);
545            return output.toByteArray();
546        }
547    
548        /**
549         * Get the contents of a <code>Reader</code> as a <code>byte[]</code>
550         * using the specified character encoding.
551         * <p>
552         * Character encoding names can be found at
553         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
554         * <p>
555         * This method buffers the input internally, so there is no need to use a
556         * <code>BufferedReader</code>.
557         * 
558         * @param input  the <code>Reader</code> to read from
559         * @param encoding  the encoding to use, null means platform default
560         * @return the requested byte array
561         * @throws NullPointerException if the input is null
562         * @throws IOException if an I/O error occurs
563         * @throws UnsupportedCharsetException
564         *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
565         *             supported.
566         * @since 1.1
567         */
568        public static byte[] toByteArray(Reader input, String encoding) throws IOException {
569            return toByteArray(input, Charsets.toCharset(encoding));
570        }
571    
572        /**
573         * Get the contents of a <code>String</code> as a <code>byte[]</code>
574         * using the default character encoding of the platform.
575         * <p>
576         * This is the same as {@link String#getBytes()}.
577         * 
578         * @param input  the <code>String</code> to convert
579         * @return the requested byte array
580         * @throws NullPointerException if the input is null
581         * @throws IOException if an I/O error occurs (never occurs)
582         * @deprecated Use {@link String#getBytes()}
583         */
584        @Deprecated
585        public static byte[] toByteArray(String input) throws IOException {
586            return input.getBytes();
587        }
588    
589        // read char[]
590        //-----------------------------------------------------------------------
591        /**
592         * Get the contents of an <code>InputStream</code> as a character array
593         * using the default character encoding of the platform.
594         * <p>
595         * This method buffers the input internally, so there is no need to use a
596         * <code>BufferedInputStream</code>.
597         * 
598         * @param is  the <code>InputStream</code> to read from
599         * @return the requested character array
600         * @throws NullPointerException if the input is null
601         * @throws IOException if an I/O error occurs
602         * @since 1.1
603         */
604        public static char[] toCharArray(InputStream is) throws IOException {
605            return toCharArray(is, Charset.defaultCharset());
606        }
607    
608        /**
609         * Get the contents of an <code>InputStream</code> as a character array
610         * using the specified character encoding.
611         * <p>
612         * This method buffers the input internally, so there is no need to use a
613         * <code>BufferedInputStream</code>.
614         * 
615         * @param is  the <code>InputStream</code> to read from
616         * @param encoding  the encoding to use, null means platform default
617         * @return the requested character array
618         * @throws NullPointerException if the input is null
619         * @throws IOException if an I/O error occurs
620         * @since 2.3
621         */
622        public static char[] toCharArray(InputStream is, Charset encoding)
623                throws IOException {
624            CharArrayWriter output = new CharArrayWriter();
625            copy(is, output, encoding);
626            return output.toCharArray();
627        }
628    
629        /**
630         * Get the contents of an <code>InputStream</code> as a character array
631         * using the specified character encoding.
632         * <p>
633         * Character encoding names can be found at
634         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
635         * <p>
636         * This method buffers the input internally, so there is no need to use a
637         * <code>BufferedInputStream</code>.
638         * 
639         * @param is  the <code>InputStream</code> to read from
640         * @param encoding  the encoding to use, null means platform default
641         * @return the requested character array
642         * @throws NullPointerException if the input is null
643         * @throws IOException if an I/O error occurs
644         * @throws UnsupportedCharsetException
645         *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
646         *             supported.
647         * @since 1.1
648         */
649        public static char[] toCharArray(InputStream is, String encoding) throws IOException {
650            return toCharArray(is, Charsets.toCharset(encoding));
651        }
652    
653        /**
654         * Get the contents of a <code>Reader</code> as a character array.
655         * <p>
656         * This method buffers the input internally, so there is no need to use a
657         * <code>BufferedReader</code>.
658         * 
659         * @param input  the <code>Reader</code> to read from
660         * @return the requested character array
661         * @throws NullPointerException if the input is null
662         * @throws IOException if an I/O error occurs
663         * @since 1.1
664         */
665        public static char[] toCharArray(Reader input) throws IOException {
666            CharArrayWriter sw = new CharArrayWriter();
667            copy(input, sw);
668            return sw.toCharArray();
669        }
670    
671        // read toString
672        //-----------------------------------------------------------------------
673        /**
674         * Get the contents of an <code>InputStream</code> as a String
675         * using the default character encoding of the platform.
676         * <p>
677         * This method buffers the input internally, so there is no need to use a
678         * <code>BufferedInputStream</code>.
679         * 
680         * @param input  the <code>InputStream</code> to read from
681         * @return the requested String
682         * @throws NullPointerException if the input is null
683         * @throws IOException if an I/O error occurs
684         */
685        public static String toString(InputStream input) throws IOException {
686            return toString(input, Charset.defaultCharset());
687        }
688    
689        /**
690         * Get the contents of an <code>InputStream</code> as a String
691         * using the specified character encoding.
692         * <p>
693         * This method buffers the input internally, so there is no need to use a
694         * <code>BufferedInputStream</code>.
695         * </p>
696         * @param input  the <code>InputStream</code> to read from
697         * @param encoding  the encoding to use, null means platform default
698         * @return the requested String
699         * @throws NullPointerException if the input is null
700         * @throws IOException if an I/O error occurs
701         * @since 2.3
702         */
703        public static String toString(InputStream input, Charset encoding) throws IOException {
704            StringBuilderWriter sw = new StringBuilderWriter();
705            copy(input, sw, encoding);
706            return sw.toString();
707        }
708    
709        /**
710         * Get the contents of an <code>InputStream</code> as a String
711         * using the specified character encoding.
712         * <p>
713         * Character encoding names can be found at
714         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
715         * <p>
716         * This method buffers the input internally, so there is no need to use a
717         * <code>BufferedInputStream</code>.
718         * 
719         * @param input  the <code>InputStream</code> to read from
720         * @param encoding  the encoding to use, null means platform default
721         * @return the requested String
722         * @throws NullPointerException if the input is null
723         * @throws IOException if an I/O error occurs
724         * @throws UnsupportedCharsetException
725         *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
726         *             supported.
727         */
728        public static String toString(InputStream input, String encoding)
729                throws IOException {
730            return toString(input, Charsets.toCharset(encoding));
731        }
732    
733        /**
734         * Get the contents of a <code>Reader</code> as a String.
735         * <p>
736         * This method buffers the input internally, so there is no need to use a
737         * <code>BufferedReader</code>.
738         * 
739         * @param input  the <code>Reader</code> to read from
740         * @return the requested String
741         * @throws NullPointerException if the input is null
742         * @throws IOException if an I/O error occurs
743         */
744        public static String toString(Reader input) throws IOException {
745            StringBuilderWriter sw = new StringBuilderWriter();
746            copy(input, sw);
747            return sw.toString();
748        }
749    
750        /**
751         * Gets the contents at the given URI.
752         * 
753         * @param uri
754         *            The URI source.
755         * @return The contents of the URL as a String.
756         * @throws IOException if an I/O exception occurs.
757         * @since 2.1.
758         */
759        public static String toString(URI uri) throws IOException {
760            return toString(uri, Charset.defaultCharset());
761        }
762    
763        /**
764         * Gets the contents at the given URI.
765         * 
766         * @param uri
767         *            The URI source.
768         * @param encoding
769         *            The encoding name for the URL contents.
770         * @return The contents of the URL as a String.
771         * @throws IOException if an I/O exception occurs.
772         * @since 2.3.
773         */
774        public static String toString(URI uri, Charset encoding) throws IOException {
775            return toString(uri.toURL(), Charsets.toCharset(encoding));
776        }
777    
778        /**
779         * Gets the contents at the given URI.
780         * 
781         * @param uri
782         *            The URI source.
783         * @param encoding
784         *            The encoding name for the URL contents.
785         * @return The contents of the URL as a String.
786         * @throws IOException if an I/O exception occurs.
787         * @throws UnsupportedCharsetException
788         *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
789         *             supported.
790         * @since 2.1.
791         */
792        public static String toString(URI uri, String encoding) throws IOException {
793            return toString(uri, Charsets.toCharset(encoding));
794        }
795    
796        /**
797         * Gets the contents at the given URL.
798         * 
799         * @param url
800         *            The URL source.
801         * @return The contents of the URL as a String.
802         * @throws IOException if an I/O exception occurs.
803         * @since 2.1.
804         */
805        public static String toString(URL url) throws IOException {
806            return toString(url, Charset.defaultCharset());
807        }
808    
809        /**
810         * Gets the contents at the given URL.
811         * 
812         * @param url
813         *            The URL source.
814         * @param encoding
815         *            The encoding name for the URL contents.
816         * @return The contents of the URL as a String.
817         * @throws IOException if an I/O exception occurs.
818         * @since 2.3
819         */
820        public static String toString(URL url, Charset encoding) throws IOException {
821            InputStream inputStream = url.openStream();
822            try {
823                return toString(inputStream, encoding);
824            } finally {
825                inputStream.close();
826            }
827        }
828    
829        /**
830         * Gets the contents at the given URL.
831         * 
832         * @param url
833         *            The URL source.
834         * @param encoding
835         *            The encoding name for the URL contents.
836         * @return The contents of the URL as a String.
837         * @throws IOException if an I/O exception occurs.
838         * @throws UnsupportedCharsetException
839         *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
840         *             supported.
841         * @since 2.1.
842         */
843        public static String toString(URL url, String encoding) throws IOException {
844            return toString(url, Charsets.toCharset(encoding));
845        }
846    
847        /**
848         * Get the contents of a <code>byte[]</code> as a String
849         * using the default character encoding of the platform.
850         * 
851         * @param input the byte array to read from
852         * @return the requested String
853         * @throws NullPointerException if the input is null
854         * @throws IOException if an I/O error occurs (never occurs)
855         * @deprecated Use {@link String#String(byte[])}
856         */
857        @Deprecated
858        public static String toString(byte[] input) throws IOException {
859            return new String(input);
860        }
861    
862        /**
863         * Get the contents of a <code>byte[]</code> as a String
864         * using the specified character encoding.
865         * <p>
866         * Character encoding names can be found at
867         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
868         * 
869         * @param input the byte array to read from
870         * @param encoding  the encoding to use, null means platform default
871         * @return the requested String
872         * @throws NullPointerException if the input is null
873         * @throws IOException if an I/O error occurs (never occurs)
874         */
875        public static String toString(byte[] input, String encoding) throws IOException {
876            return new String(input, Charsets.toCharset(encoding));
877        }
878    
879        // readLines
880        //-----------------------------------------------------------------------
881        /**
882         * Get the contents of an <code>InputStream</code> as a list of Strings,
883         * one entry per line, using the default character encoding of the platform.
884         * <p>
885         * This method buffers the input internally, so there is no need to use a
886         * <code>BufferedInputStream</code>.
887         *
888         * @param input  the <code>InputStream</code> to read from, not null
889         * @return the list of Strings, never null
890         * @throws NullPointerException if the input is null
891         * @throws IOException if an I/O error occurs
892         * @since 1.1
893         */
894        public static List<String> readLines(InputStream input) throws IOException {
895            return readLines(input, Charset.defaultCharset());
896        }
897    
898        /**
899         * Get the contents of an <code>InputStream</code> as a list of Strings,
900         * one entry per line, using the specified character encoding.
901         * <p>
902         * This method buffers the input internally, so there is no need to use a
903         * <code>BufferedInputStream</code>.
904         *
905         * @param input  the <code>InputStream</code> to read from, not null
906         * @param encoding  the encoding to use, null means platform default
907         * @return the list of Strings, never null
908         * @throws NullPointerException if the input is null
909         * @throws IOException if an I/O error occurs
910         * @since 2.3
911         */
912        public static List<String> readLines(InputStream input, Charset encoding) throws IOException {
913            InputStreamReader reader = new InputStreamReader(input, Charsets.toCharset(encoding));
914            return readLines(reader);
915        }
916    
917        /**
918         * Get the contents of an <code>InputStream</code> as a list of Strings,
919         * one entry per line, using the specified character encoding.
920         * <p>
921         * Character encoding names can be found at
922         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
923         * <p>
924         * This method buffers the input internally, so there is no need to use a
925         * <code>BufferedInputStream</code>.
926         *
927         * @param input  the <code>InputStream</code> to read from, not null
928         * @param encoding  the encoding to use, null means platform default
929         * @return the list of Strings, never null
930         * @throws NullPointerException if the input is null
931         * @throws IOException if an I/O error occurs
932         * @throws UnsupportedCharsetException
933         *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
934         *             supported.
935         * @since 1.1
936         */
937        public static List<String> readLines(InputStream input, String encoding) throws IOException {
938            return readLines(input, Charsets.toCharset(encoding));
939        }
940    
941        /**
942         * Get the contents of a <code>Reader</code> as a list of Strings,
943         * one entry per line.
944         * <p>
945         * This method buffers the input internally, so there is no need to use a
946         * <code>BufferedReader</code>.
947         *
948         * @param input  the <code>Reader</code> to read from, not null
949         * @return the list of Strings, never null
950         * @throws NullPointerException if the input is null
951         * @throws IOException if an I/O error occurs
952         * @since 1.1
953         */
954        public static List<String> readLines(Reader input) throws IOException {
955            BufferedReader reader = toBufferedReader(input);
956            List<String> list = new ArrayList<String>();
957            String line = reader.readLine();
958            while (line != null) {
959                list.add(line);
960                line = reader.readLine();
961            }
962            return list;
963        }
964    
965        // lineIterator
966        //-----------------------------------------------------------------------
967        /**
968         * Return an Iterator for the lines in a <code>Reader</code>.
969         * <p>
970         * <code>LineIterator</code> holds a reference to the open
971         * <code>Reader</code> specified here. When you have finished with the
972         * iterator you should close the reader to free internal resources.
973         * This can be done by closing the reader directly, or by calling
974         * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
975         * <p>
976         * The recommended usage pattern is:
977         * <pre>
978         * try {
979         *   LineIterator it = IOUtils.lineIterator(reader);
980         *   while (it.hasNext()) {
981         *     String line = it.nextLine();
982         *     /// do something with line
983         *   }
984         * } finally {
985         *   IOUtils.closeQuietly(reader);
986         * }
987         * </pre>
988         *
989         * @param reader  the <code>Reader</code> to read from, not null
990         * @return an Iterator of the lines in the reader, never null
991         * @throws IllegalArgumentException if the reader is null
992         * @since 1.2
993         */
994        public static LineIterator lineIterator(Reader reader) {
995            return new LineIterator(reader);
996        }
997    
998        /**
999         * Return an Iterator for the lines in an <code>InputStream</code>, using
1000         * the character encoding specified (or default encoding if null).
1001         * <p>
1002         * <code>LineIterator</code> holds a reference to the open
1003         * <code>InputStream</code> specified here. When you have finished with
1004         * the iterator you should close the stream to free internal resources.
1005         * This can be done by closing the stream directly, or by calling
1006         * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
1007         * <p>
1008         * The recommended usage pattern is:
1009         * <pre>
1010         * try {
1011         *   LineIterator it = IOUtils.lineIterator(stream, charset);
1012         *   while (it.hasNext()) {
1013         *     String line = it.nextLine();
1014         *     /// do something with line
1015         *   }
1016         * } finally {
1017         *   IOUtils.closeQuietly(stream);
1018         * }
1019         * </pre>
1020         *
1021         * @param input  the <code>InputStream</code> to read from, not null
1022         * @param encoding  the encoding to use, null means platform default
1023         * @return an Iterator of the lines in the reader, never null
1024         * @throws IllegalArgumentException if the input is null
1025         * @throws IOException if an I/O error occurs, such as if the encoding is invalid
1026         * @since 2.3
1027         */
1028        public static LineIterator lineIterator(InputStream input, Charset encoding) throws IOException {
1029            return new LineIterator(new InputStreamReader(input, Charsets.toCharset(encoding)));
1030        }
1031    
1032        /**
1033         * Return an Iterator for the lines in an <code>InputStream</code>, using
1034         * the character encoding specified (or default encoding if null).
1035         * <p>
1036         * <code>LineIterator</code> holds a reference to the open
1037         * <code>InputStream</code> specified here. When you have finished with
1038         * the iterator you should close the stream to free internal resources.
1039         * This can be done by closing the stream directly, or by calling
1040         * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
1041         * <p>
1042         * The recommended usage pattern is:
1043         * <pre>
1044         * try {
1045         *   LineIterator it = IOUtils.lineIterator(stream, "UTF-8");
1046         *   while (it.hasNext()) {
1047         *     String line = it.nextLine();
1048         *     /// do something with line
1049         *   }
1050         * } finally {
1051         *   IOUtils.closeQuietly(stream);
1052         * }
1053         * </pre>
1054         *
1055         * @param input  the <code>InputStream</code> to read from, not null
1056         * @param encoding  the encoding to use, null means platform default
1057         * @return an Iterator of the lines in the reader, never null
1058         * @throws IllegalArgumentException if the input is null
1059         * @throws IOException if an I/O error occurs, such as if the encoding is invalid
1060         * @throws UnsupportedCharsetException
1061         *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1062         *             supported.
1063         * @since 1.2
1064         */
1065        public static LineIterator lineIterator(InputStream input, String encoding) throws IOException {
1066            return lineIterator(input, Charsets.toCharset(encoding));
1067        }
1068    
1069        //-----------------------------------------------------------------------
1070        /**
1071         * Convert the specified CharSequence to an input stream, encoded as bytes
1072         * using the default character encoding of the platform.
1073         *
1074         * @param input the CharSequence to convert
1075         * @return an input stream
1076         * @since 2.0
1077         */
1078        public static InputStream toInputStream(CharSequence input) {
1079            return toInputStream(input, Charset.defaultCharset());
1080        }
1081    
1082        /**
1083         * Convert the specified CharSequence to an input stream, encoded as bytes
1084         * using the specified character encoding.
1085         *
1086         * @param input the CharSequence to convert
1087         * @param encoding the encoding to use, null means platform default
1088         * @return an input stream
1089         * @since 2.3
1090         */
1091        public static InputStream toInputStream(CharSequence input, Charset encoding) {
1092            return toInputStream(input.toString(), encoding);
1093        }
1094    
1095        /**
1096         * Convert the specified CharSequence to an input stream, encoded as bytes
1097         * using the specified character encoding.
1098         * <p>
1099         * Character encoding names can be found at
1100         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1101         *
1102         * @param input the CharSequence to convert
1103         * @param encoding the encoding to use, null means platform default
1104         * @return an input stream
1105         * @throws IOException if the encoding is invalid
1106         * @throws UnsupportedCharsetException
1107         *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1108         *             supported.
1109         * @since 2.0
1110         */
1111        public static InputStream toInputStream(CharSequence input, String encoding) throws IOException {
1112            return toInputStream(input, Charsets.toCharset(encoding));
1113        }
1114    
1115        //-----------------------------------------------------------------------
1116        /**
1117         * Convert the specified string to an input stream, encoded as bytes
1118         * using the default character encoding of the platform.
1119         *
1120         * @param input the string to convert
1121         * @return an input stream
1122         * @since 1.1
1123         */
1124        public static InputStream toInputStream(String input) {
1125            return toInputStream(input, Charset.defaultCharset());
1126        }
1127    
1128        /**
1129         * Convert the specified string to an input stream, encoded as bytes
1130         * using the specified character encoding.
1131         *
1132         * @param input the string to convert
1133         * @param encoding the encoding to use, null means platform default
1134         * @return an input stream
1135         * @since 2.3
1136         */
1137        public static InputStream toInputStream(String input, Charset encoding) {
1138            return new ByteArrayInputStream(input.getBytes(Charsets.toCharset(encoding)));
1139        }
1140    
1141        /**
1142         * Convert the specified string to an input stream, encoded as bytes
1143         * using the specified character encoding.
1144         * <p>
1145         * Character encoding names can be found at
1146         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1147         *
1148         * @param input the string to convert
1149         * @param encoding the encoding to use, null means platform default
1150         * @return an input stream
1151         * @throws IOException if the encoding is invalid
1152         * @throws UnsupportedCharsetException
1153         *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1154         *             supported.
1155         * @since 1.1
1156         */
1157        public static InputStream toInputStream(String input, String encoding) throws IOException {
1158            byte[] bytes = input.getBytes(Charsets.toCharset(encoding));
1159            return new ByteArrayInputStream(bytes);
1160        }
1161    
1162        // write byte[]
1163        //-----------------------------------------------------------------------
1164        /**
1165         * Writes bytes from a <code>byte[]</code> to an <code>OutputStream</code>.
1166         * 
1167         * @param data  the byte array to write, do not modify during output,
1168         * null ignored
1169         * @param output  the <code>OutputStream</code> to write to
1170         * @throws NullPointerException if output is null
1171         * @throws IOException if an I/O error occurs
1172         * @since 1.1
1173         */
1174        public static void write(byte[] data, OutputStream output)
1175                throws IOException {
1176            if (data != null) {
1177                output.write(data);
1178            }
1179        }
1180    
1181        /**
1182         * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code>
1183         * using the default character encoding of the platform.
1184         * <p>
1185         * This method uses {@link String#String(byte[])}.
1186         * 
1187         * @param data  the byte array to write, do not modify during output,
1188         * null ignored
1189         * @param output  the <code>Writer</code> to write to
1190         * @throws NullPointerException if output is null
1191         * @throws IOException if an I/O error occurs
1192         * @since 1.1
1193         */
1194        public static void write(byte[] data, Writer output) throws IOException {
1195            write(data, output, Charset.defaultCharset());
1196        }
1197    
1198        /**
1199         * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code>
1200         * using the specified character encoding.
1201         * <p>
1202         * This method uses {@link String#String(byte[], String)}.
1203         * 
1204         * @param data  the byte array to write, do not modify during output,
1205         * null ignored
1206         * @param output  the <code>Writer</code> to write to
1207         * @param encoding  the encoding to use, null means platform default
1208         * @throws NullPointerException if output is null
1209         * @throws IOException if an I/O error occurs
1210         * @since 2.3
1211         */
1212        public static void write(byte[] data, Writer output, Charset encoding) throws IOException {
1213            if (data != null) {
1214                output.write(new String(data, Charsets.toCharset(encoding)));
1215            }
1216        }
1217    
1218        /**
1219         * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code>
1220         * using the specified character encoding.
1221         * <p>
1222         * Character encoding names can be found at
1223         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1224         * <p>
1225         * This method uses {@link String#String(byte[], String)}.
1226         * 
1227         * @param data  the byte array to write, do not modify during output,
1228         * null ignored
1229         * @param output  the <code>Writer</code> to write to
1230         * @param encoding  the encoding to use, null means platform default
1231         * @throws NullPointerException if output is null
1232         * @throws IOException if an I/O error occurs
1233         * @throws UnsupportedCharsetException
1234         *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1235         *             supported.
1236         * @since 1.1
1237         */
1238        public static void write(byte[] data, Writer output, String encoding) throws IOException {
1239            write(data, output, Charsets.toCharset(encoding));
1240        }
1241    
1242        // write char[]
1243        //-----------------------------------------------------------------------
1244        /**
1245         * Writes chars from a <code>char[]</code> to a <code>Writer</code>
1246         * using the default character encoding of the platform.
1247         * 
1248         * @param data  the char array to write, do not modify during output,
1249         * null ignored
1250         * @param output  the <code>Writer</code> to write to
1251         * @throws NullPointerException if output is null
1252         * @throws IOException if an I/O error occurs
1253         * @since 1.1
1254         */
1255        public static void write(char[] data, Writer output) throws IOException {
1256            if (data != null) {
1257                output.write(data);
1258            }
1259        }
1260    
1261        /**
1262         * Writes chars from a <code>char[]</code> to bytes on an
1263         * <code>OutputStream</code>.
1264         * <p>
1265         * This method uses {@link String#String(char[])} and
1266         * {@link String#getBytes()}.
1267         * 
1268         * @param data  the char array to write, do not modify during output,
1269         * null ignored
1270         * @param output  the <code>OutputStream</code> to write to
1271         * @throws NullPointerException if output is null
1272         * @throws IOException if an I/O error occurs
1273         * @since 1.1
1274         */
1275        public static void write(char[] data, OutputStream output)
1276                throws IOException {
1277            write(data, output, Charset.defaultCharset());
1278        }
1279    
1280        /**
1281         * Writes chars from a <code>char[]</code> to bytes on an
1282         * <code>OutputStream</code> using the specified character encoding.
1283         * <p>
1284         * This method uses {@link String#String(char[])} and
1285         * {@link String#getBytes(String)}.
1286         * 
1287         * @param data  the char array to write, do not modify during output,
1288         * null ignored
1289         * @param output  the <code>OutputStream</code> to write to
1290         * @param encoding  the encoding to use, null means platform default
1291         * @throws NullPointerException if output is null
1292         * @throws IOException if an I/O error occurs
1293         * @since 2.3
1294         */
1295        public static void write(char[] data, OutputStream output, Charset encoding) throws IOException {
1296            if (data != null) {
1297                output.write(new String(data).getBytes(Charsets.toCharset(encoding)));
1298            }
1299        }
1300    
1301        /**
1302         * Writes chars from a <code>char[]</code> to bytes on an
1303         * <code>OutputStream</code> using the specified character encoding.
1304         * <p>
1305         * Character encoding names can be found at
1306         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1307         * <p>
1308         * This method uses {@link String#String(char[])} and
1309         * {@link String#getBytes(String)}.
1310         * 
1311         * @param data  the char array to write, do not modify during output,
1312         * null ignored
1313         * @param output  the <code>OutputStream</code> to write to
1314         * @param encoding  the encoding to use, null means platform default
1315         * @throws NullPointerException if output is null
1316         * @throws IOException if an I/O error occurs
1317         * @throws UnsupportedCharsetException
1318         *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1319         *             supported.
1320         * @since 1.1
1321         */
1322        public static void write(char[] data, OutputStream output, String encoding)
1323                throws IOException {
1324            write(data, output, Charsets.toCharset(encoding));
1325        }
1326    
1327        // write CharSequence
1328        //-----------------------------------------------------------------------
1329        /**
1330         * Writes chars from a <code>CharSequence</code> to a <code>Writer</code>.
1331         * 
1332         * @param data  the <code>CharSequence</code> to write, null ignored
1333         * @param output  the <code>Writer</code> to write to
1334         * @throws NullPointerException if output is null
1335         * @throws IOException if an I/O error occurs
1336         * @since 2.0
1337         */
1338        public static void write(CharSequence data, Writer output) throws IOException {
1339            if (data != null) {
1340                write(data.toString(), output);
1341            }
1342        }
1343    
1344        /**
1345         * Writes chars from a <code>CharSequence</code> to bytes on an
1346         * <code>OutputStream</code> using the default character encoding of the
1347         * platform.
1348         * <p>
1349         * This method uses {@link String#getBytes()}.
1350         * 
1351         * @param data  the <code>CharSequence</code> to write, null ignored
1352         * @param output  the <code>OutputStream</code> to write to
1353         * @throws NullPointerException if output is null
1354         * @throws IOException if an I/O error occurs
1355         * @since 2.0
1356         */
1357        public static void write(CharSequence data, OutputStream output)
1358                throws IOException {
1359            write(data, output, Charset.defaultCharset());
1360        }
1361    
1362        /**
1363         * Writes chars from a <code>CharSequence</code> to bytes on an
1364         * <code>OutputStream</code> using the specified character encoding.
1365         * <p>
1366         * This method uses {@link String#getBytes(String)}.
1367         * 
1368         * @param data  the <code>CharSequence</code> to write, null ignored
1369         * @param output  the <code>OutputStream</code> to write to
1370         * @param encoding  the encoding to use, null means platform default
1371         * @throws NullPointerException if output is null
1372         * @throws IOException if an I/O error occurs
1373         * @since 2.3
1374         */
1375        public static void write(CharSequence data, OutputStream output, Charset encoding) throws IOException {
1376            if (data != null) {
1377                write(data.toString(), output, encoding);
1378            }
1379        }
1380    
1381        /**
1382         * Writes chars from a <code>CharSequence</code> to bytes on an
1383         * <code>OutputStream</code> using the specified character encoding.
1384         * <p>
1385         * Character encoding names can be found at
1386         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1387         * <p>
1388         * This method uses {@link String#getBytes(String)}.
1389         * 
1390         * @param data  the <code>CharSequence</code> to write, null ignored
1391         * @param output  the <code>OutputStream</code> to write to
1392         * @param encoding  the encoding to use, null means platform default
1393         * @throws NullPointerException if output is null
1394         * @throws IOException if an I/O error occurs
1395         * @throws UnsupportedCharsetException
1396         *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1397         *             supported.
1398         * @since 2.0
1399         */
1400        public static void write(CharSequence data, OutputStream output, String encoding) throws IOException {
1401            write(data, output, Charsets.toCharset(encoding));
1402        }
1403    
1404        // write String
1405        //-----------------------------------------------------------------------
1406        /**
1407         * Writes chars from a <code>String</code> to a <code>Writer</code>.
1408         * 
1409         * @param data  the <code>String</code> to write, null ignored
1410         * @param output  the <code>Writer</code> to write to
1411         * @throws NullPointerException if output is null
1412         * @throws IOException if an I/O error occurs
1413         * @since 1.1
1414         */
1415        public static void write(String data, Writer output) throws IOException {
1416            if (data != null) {
1417                output.write(data);
1418            }
1419        }
1420    
1421        /**
1422         * Writes chars from a <code>String</code> to bytes on an
1423         * <code>OutputStream</code> using the default character encoding of the
1424         * platform.
1425         * <p>
1426         * This method uses {@link String#getBytes()}.
1427         * 
1428         * @param data  the <code>String</code> to write, null ignored
1429         * @param output  the <code>OutputStream</code> to write to
1430         * @throws NullPointerException if output is null
1431         * @throws IOException if an I/O error occurs
1432         * @since 1.1
1433         */
1434        public static void write(String data, OutputStream output)
1435                throws IOException {
1436            write(data, output, Charset.defaultCharset());
1437        }
1438    
1439        /**
1440         * Writes chars from a <code>String</code> to bytes on an
1441         * <code>OutputStream</code> using the specified character encoding.
1442         * <p>
1443         * This method uses {@link String#getBytes(String)}.
1444         * 
1445         * @param data  the <code>String</code> to write, null ignored
1446         * @param output  the <code>OutputStream</code> to write to
1447         * @param encoding  the encoding to use, null means platform default
1448         * @throws NullPointerException if output is null
1449         * @throws IOException if an I/O error occurs
1450         * @since 2.3
1451         */
1452        public static void write(String data, OutputStream output, Charset encoding) throws IOException {
1453            if (data != null) {
1454                output.write(data.getBytes(Charsets.toCharset(encoding)));
1455            }
1456        }
1457    
1458        /**
1459         * Writes chars from a <code>String</code> to bytes on an
1460         * <code>OutputStream</code> using the specified character encoding.
1461         * <p>
1462         * Character encoding names can be found at
1463         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1464         * <p>
1465         * This method uses {@link String#getBytes(String)}.
1466         * 
1467         * @param data  the <code>String</code> to write, null ignored
1468         * @param output  the <code>OutputStream</code> to write to
1469         * @param encoding  the encoding to use, null means platform default
1470         * @throws NullPointerException if output is null
1471         * @throws IOException if an I/O error occurs
1472         * @throws UnsupportedCharsetException
1473         *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1474         *             supported.
1475         * @since 1.1
1476         */
1477        public static void write(String data, OutputStream output, String encoding)
1478                throws IOException {
1479            write(data, output, Charsets.toCharset(encoding));
1480        }
1481    
1482        // write StringBuffer
1483        //-----------------------------------------------------------------------
1484        /**
1485         * Writes chars from a <code>StringBuffer</code> to a <code>Writer</code>.
1486         * 
1487         * @param data  the <code>StringBuffer</code> to write, null ignored
1488         * @param output  the <code>Writer</code> to write to
1489         * @throws NullPointerException if output is null
1490         * @throws IOException if an I/O error occurs
1491         * @since 1.1
1492         * @deprecated replaced by write(CharSequence, Writer)
1493         */
1494        @Deprecated
1495        public static void write(StringBuffer data, Writer output)
1496                throws IOException {
1497            if (data != null) {
1498                output.write(data.toString());
1499            }
1500        }
1501    
1502        /**
1503         * Writes chars from a <code>StringBuffer</code> to bytes on an
1504         * <code>OutputStream</code> using the default character encoding of the
1505         * platform.
1506         * <p>
1507         * This method uses {@link String#getBytes()}.
1508         * 
1509         * @param data  the <code>StringBuffer</code> to write, null ignored
1510         * @param output  the <code>OutputStream</code> to write to
1511         * @throws NullPointerException if output is null
1512         * @throws IOException if an I/O error occurs
1513         * @since 1.1
1514         * @deprecated replaced by write(CharSequence, OutputStream)
1515         */
1516        @Deprecated
1517        public static void write(StringBuffer data, OutputStream output)
1518                throws IOException {
1519            write(data, output, (String) null);
1520        }
1521    
1522        /**
1523         * Writes chars from a <code>StringBuffer</code> to bytes on an
1524         * <code>OutputStream</code> using the specified character encoding.
1525         * <p>
1526         * Character encoding names can be found at
1527         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1528         * <p>
1529         * This method uses {@link String#getBytes(String)}.
1530         * 
1531         * @param data  the <code>StringBuffer</code> to write, null ignored
1532         * @param output  the <code>OutputStream</code> to write to
1533         * @param encoding  the encoding to use, null means platform default
1534         * @throws NullPointerException if output is null
1535         * @throws IOException if an I/O error occurs
1536         * @throws UnsupportedCharsetException
1537         *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1538         *             supported.
1539         * @since 1.1
1540         * @deprecated replaced by write(CharSequence, OutputStream, String)
1541         */
1542        @Deprecated
1543        public static void write(StringBuffer data, OutputStream output, String encoding) throws IOException {
1544            if (data != null) {
1545                output.write(data.toString().getBytes(Charsets.toCharset(encoding)));
1546            }
1547        }
1548    
1549        // writeLines
1550        //-----------------------------------------------------------------------
1551        /**
1552         * Writes the <code>toString()</code> value of each item in a collection to
1553         * an <code>OutputStream</code> line by line, using the default character
1554         * encoding of the platform and the specified line ending.
1555         *
1556         * @param lines  the lines to write, null entries produce blank lines
1557         * @param lineEnding  the line separator to use, null is system default
1558         * @param output  the <code>OutputStream</code> to write to, not null, not closed
1559         * @throws NullPointerException if the output is null
1560         * @throws IOException if an I/O error occurs
1561         * @since 1.1
1562         */
1563        public static void writeLines(Collection<?> lines, String lineEnding,
1564                OutputStream output) throws IOException {
1565            writeLines(lines, lineEnding, output, Charset.defaultCharset());
1566        }
1567    
1568        /**
1569         * Writes the <code>toString()</code> value of each item in a collection to
1570         * an <code>OutputStream</code> line by line, using the specified character
1571         * encoding and the specified line ending.
1572         *
1573         * @param lines  the lines to write, null entries produce blank lines
1574         * @param lineEnding  the line separator to use, null is system default
1575         * @param output  the <code>OutputStream</code> to write to, not null, not closed
1576         * @param encoding  the encoding to use, null means platform default
1577         * @throws NullPointerException if the output is null
1578         * @throws IOException if an I/O error occurs
1579         * @since 2.3
1580         */
1581        public static void writeLines(Collection<?> lines, String lineEnding, OutputStream output, Charset encoding)
1582                throws IOException {
1583            if (lines == null) {
1584                return;
1585            }
1586            if (lineEnding == null) {
1587                lineEnding = LINE_SEPARATOR;
1588            }
1589            Charset cs = Charsets.toCharset(encoding);
1590            for (Object line : lines) {
1591                if (line != null) {
1592                    output.write(line.toString().getBytes(cs));
1593                }
1594                output.write(lineEnding.getBytes(cs));
1595            }
1596        }
1597    
1598        /**
1599         * Writes the <code>toString()</code> value of each item in a collection to
1600         * an <code>OutputStream</code> line by line, using the specified character
1601         * encoding and the specified line ending.
1602         * <p>
1603         * Character encoding names can be found at
1604         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1605         *
1606         * @param lines  the lines to write, null entries produce blank lines
1607         * @param lineEnding  the line separator to use, null is system default
1608         * @param output  the <code>OutputStream</code> to write to, not null, not closed
1609         * @param encoding  the encoding to use, null means platform default
1610         * @throws NullPointerException if the output is null
1611         * @throws IOException if an I/O error occurs
1612         * @throws UnsupportedCharsetException
1613         *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1614         *             supported.
1615         * @since 1.1
1616         */
1617        public static void writeLines(Collection<?> lines, String lineEnding,
1618                OutputStream output, String encoding) throws IOException {
1619            writeLines(lines, lineEnding, output, Charsets.toCharset(encoding));
1620        }
1621    
1622        /**
1623         * Writes the <code>toString()</code> value of each item in a collection to
1624         * a <code>Writer</code> line by line, using the specified line ending.
1625         *
1626         * @param lines  the lines to write, null entries produce blank lines
1627         * @param lineEnding  the line separator to use, null is system default
1628         * @param writer  the <code>Writer</code> to write to, not null, not closed
1629         * @throws NullPointerException if the input is null
1630         * @throws IOException if an I/O error occurs
1631         * @since 1.1
1632         */
1633        public static void writeLines(Collection<?> lines, String lineEnding,
1634                Writer writer) throws IOException {
1635            if (lines == null) {
1636                return;
1637            }
1638            if (lineEnding == null) {
1639                lineEnding = LINE_SEPARATOR;
1640            }
1641            for (Object line : lines) {
1642                if (line != null) {
1643                    writer.write(line.toString());
1644                }
1645                writer.write(lineEnding);
1646            }
1647        }
1648    
1649        // copy from InputStream
1650        //-----------------------------------------------------------------------
1651        /**
1652         * Copy bytes from an <code>InputStream</code> to an
1653         * <code>OutputStream</code>.
1654         * <p>
1655         * This method buffers the input internally, so there is no need to use a
1656         * <code>BufferedInputStream</code>.
1657         * <p>
1658         * Large streams (over 2GB) will return a bytes copied value of
1659         * <code>-1</code> after the copy has completed since the correct
1660         * number of bytes cannot be returned as an int. For large streams
1661         * use the <code>copyLarge(InputStream, OutputStream)</code> method.
1662         * 
1663         * @param input  the <code>InputStream</code> to read from
1664         * @param output  the <code>OutputStream</code> to write to
1665         * @return the number of bytes copied, or -1 if &gt; Integer.MAX_VALUE
1666         * @throws NullPointerException if the input or output is null
1667         * @throws IOException if an I/O error occurs
1668         * @since 1.1
1669         */
1670        public static int copy(InputStream input, OutputStream output) throws IOException {
1671            long count = copyLarge(input, output);
1672            if (count > Integer.MAX_VALUE) {
1673                return -1;
1674            }
1675            return (int) count;
1676        }
1677    
1678        /**
1679         * Copy bytes from a large (over 2GB) <code>InputStream</code> to an
1680         * <code>OutputStream</code>.
1681         * <p>
1682         * This method buffers the input internally, so there is no need to use a
1683         * <code>BufferedInputStream</code>.
1684         * <p>
1685         * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
1686         * 
1687         * @param input  the <code>InputStream</code> to read from
1688         * @param output  the <code>OutputStream</code> to write to
1689         * @return the number of bytes copied
1690         * @throws NullPointerException if the input or output is null
1691         * @throws IOException if an I/O error occurs
1692         * @since 1.3
1693         */
1694        public static long copyLarge(InputStream input, OutputStream output)
1695                throws IOException {
1696            return copyLarge(input, output, new byte[DEFAULT_BUFFER_SIZE]);
1697        }
1698    
1699        /**
1700         * Copy bytes from a large (over 2GB) <code>InputStream</code> to an
1701         * <code>OutputStream</code>.
1702         * <p>
1703         * This method uses the provided buffer, so there is no need to use a
1704         * <code>BufferedInputStream</code>.
1705         * <p>
1706         * 
1707         * @param input  the <code>InputStream</code> to read from
1708         * @param output  the <code>OutputStream</code> to write to
1709         * @param buffer the buffer to use for the copy
1710         * @return the number of bytes copied
1711         * @throws NullPointerException if the input or output is null
1712         * @throws IOException if an I/O error occurs
1713         * @since 2.2
1714         */
1715        public static long copyLarge(InputStream input, OutputStream output, byte[] buffer)
1716                throws IOException {
1717            long count = 0;
1718            int n = 0;
1719            while (EOF != (n = input.read(buffer))) {
1720                output.write(buffer, 0, n);
1721                count += n;
1722            }
1723            return count;
1724        }
1725    
1726        /**
1727         * Copy some or all bytes from a large (over 2GB) <code>InputStream</code> to an
1728         * <code>OutputStream</code>, optionally skipping input bytes.
1729         * <p>
1730         * This method buffers the input internally, so there is no need to use a
1731         * <code>BufferedInputStream</code>.
1732         * <p>
1733         * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
1734         * 
1735         * @param input  the <code>InputStream</code> to read from
1736         * @param output  the <code>OutputStream</code> to write to
1737         * @param inputOffset : number of bytes to skip from input before copying
1738         *         -ve values are ignored
1739         * @param length : number of bytes to copy. -ve means all
1740         * @return the number of bytes copied
1741         * @throws NullPointerException if the input or output is null
1742         * @throws IOException if an I/O error occurs
1743         * @since 2.2
1744         */
1745        public static long copyLarge(InputStream input, OutputStream output, long inputOffset, long length)
1746                throws IOException {
1747            return copyLarge(input, output, inputOffset, length, new byte[DEFAULT_BUFFER_SIZE]);
1748        }
1749    
1750        /**
1751         * Copy some or all bytes from a large (over 2GB) <code>InputStream</code> to an
1752         * <code>OutputStream</code>, optionally skipping input bytes.
1753         * <p>
1754         * This method uses the provided buffer, so there is no need to use a
1755         * <code>BufferedInputStream</code>.
1756         * <p>
1757         * 
1758         * @param input  the <code>InputStream</code> to read from
1759         * @param output  the <code>OutputStream</code> to write to
1760         * @param inputOffset : number of bytes to skip from input before copying
1761         *         -ve values are ignored
1762         * @param length : number of bytes to copy. -ve means all
1763         * @param buffer the buffer to use for the copy
1764         *
1765         * @return the number of bytes copied
1766         * @throws NullPointerException if the input or output is null
1767         * @throws IOException if an I/O error occurs
1768         * @since 2.2
1769         */
1770        public static long copyLarge(InputStream input, OutputStream output, 
1771                final long inputOffset, final long length, byte[] buffer)  throws IOException {
1772            if (inputOffset > 0) {
1773                skipFully(input, inputOffset);
1774            }
1775            if (length == 0) {
1776                return 0;
1777            }
1778            final int bufferLength = buffer.length;
1779            int bytesToRead = bufferLength;
1780            if (length > 0 && length < bufferLength) {
1781                bytesToRead = (int) length;
1782            }
1783            int read;
1784            long totalRead = 0;
1785            while (bytesToRead > 0 && EOF != (read = input.read(buffer, 0, bytesToRead))) {
1786                output.write(buffer, 0, read);
1787                totalRead += read;
1788                if (length > 0) { // only adjust length if not reading to the end
1789                    // Note the cast must work because buffer.length is an integer
1790                    bytesToRead = (int) Math.min(length - totalRead, bufferLength);
1791                }
1792            }
1793            return totalRead;
1794        }
1795    
1796        /**
1797         * Copy bytes from an <code>InputStream</code> to chars on a
1798         * <code>Writer</code> using the default character encoding of the platform.
1799         * <p>
1800         * This method buffers the input internally, so there is no need to use a
1801         * <code>BufferedInputStream</code>.
1802         * <p>
1803         * This method uses {@link InputStreamReader}.
1804         *
1805         * @param input  the <code>InputStream</code> to read from
1806         * @param output  the <code>Writer</code> to write to
1807         * @throws NullPointerException if the input or output is null
1808         * @throws IOException if an I/O error occurs
1809         * @since 1.1
1810         */
1811        public static void copy(InputStream input, Writer output)
1812                throws IOException {
1813            copy(input, output, Charset.defaultCharset());
1814        }
1815    
1816        /**
1817         * Copy bytes from an <code>InputStream</code> to chars on a
1818         * <code>Writer</code> using the specified character encoding.
1819         * <p>
1820         * This method buffers the input internally, so there is no need to use a
1821         * <code>BufferedInputStream</code>.
1822         * <p>
1823         * This method uses {@link InputStreamReader}.
1824         *
1825         * @param input  the <code>InputStream</code> to read from
1826         * @param output  the <code>Writer</code> to write to
1827         * @param encoding  the encoding to use, null means platform default
1828         * @throws NullPointerException if the input or output is null
1829         * @throws IOException if an I/O error occurs
1830         * @since 2.3
1831         */
1832        public static void copy(InputStream input, Writer output, Charset encoding) throws IOException {
1833            InputStreamReader in = new InputStreamReader(input, Charsets.toCharset(encoding));
1834            copy(in, output);
1835        }
1836    
1837        /**
1838         * Copy bytes from an <code>InputStream</code> to chars on a
1839         * <code>Writer</code> using the specified character encoding.
1840         * <p>
1841         * This method buffers the input internally, so there is no need to use a
1842         * <code>BufferedInputStream</code>.
1843         * <p>
1844         * Character encoding names can be found at
1845         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1846         * <p>
1847         * This method uses {@link InputStreamReader}.
1848         *
1849         * @param input  the <code>InputStream</code> to read from
1850         * @param output  the <code>Writer</code> to write to
1851         * @param encoding  the encoding to use, null means platform default
1852         * @throws NullPointerException if the input or output is null
1853         * @throws IOException if an I/O error occurs
1854         * @throws UnsupportedCharsetException
1855         *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1856         *             supported.
1857         * @since 1.1
1858         */
1859        public static void copy(InputStream input, Writer output, String encoding) throws IOException {
1860            copy(input, output, Charsets.toCharset(encoding));
1861        }
1862    
1863        // copy from Reader
1864        //-----------------------------------------------------------------------
1865        /**
1866         * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
1867         * <p>
1868         * This method buffers the input internally, so there is no need to use a
1869         * <code>BufferedReader</code>.
1870         * <p>
1871         * Large streams (over 2GB) will return a chars copied value of
1872         * <code>-1</code> after the copy has completed since the correct
1873         * number of chars cannot be returned as an int. For large streams
1874         * use the <code>copyLarge(Reader, Writer)</code> method.
1875         *
1876         * @param input  the <code>Reader</code> to read from
1877         * @param output  the <code>Writer</code> to write to
1878         * @return the number of characters copied, or -1 if &gt; Integer.MAX_VALUE
1879         * @throws NullPointerException if the input or output is null
1880         * @throws IOException if an I/O error occurs
1881         * @since 1.1
1882         */
1883        public static int copy(Reader input, Writer output) throws IOException {
1884            long count = copyLarge(input, output);
1885            if (count > Integer.MAX_VALUE) {
1886                return -1;
1887            }
1888            return (int) count;
1889        }
1890    
1891        /**
1892         * Copy chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>.
1893         * <p>
1894         * This method buffers the input internally, so there is no need to use a
1895         * <code>BufferedReader</code>.
1896         * <p>
1897         * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
1898         *
1899         * @param input  the <code>Reader</code> to read from
1900         * @param output  the <code>Writer</code> to write to
1901         * @return the number of characters copied
1902         * @throws NullPointerException if the input or output is null
1903         * @throws IOException if an I/O error occurs
1904         * @since 1.3
1905         */
1906        public static long copyLarge(Reader input, Writer output) throws IOException {
1907            return copyLarge(input, output, new char[DEFAULT_BUFFER_SIZE]);
1908        }
1909    
1910        /**
1911         * Copy chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>.
1912         * <p>
1913         * This method uses the provided buffer, so there is no need to use a
1914         * <code>BufferedReader</code>.
1915         * <p>
1916         *
1917         * @param input  the <code>Reader</code> to read from
1918         * @param output  the <code>Writer</code> to write to
1919         * @param buffer the buffer to be used for the copy
1920         * @return the number of characters copied
1921         * @throws NullPointerException if the input or output is null
1922         * @throws IOException if an I/O error occurs
1923         * @since 2.2
1924         */
1925        public static long copyLarge(Reader input, Writer output, char [] buffer) throws IOException {
1926            long count = 0;
1927            int n = 0;
1928            while (EOF != (n = input.read(buffer))) {
1929                output.write(buffer, 0, n);
1930                count += n;
1931            }
1932            return count;
1933        }
1934    
1935        /**
1936         * Copy some or all chars from a large (over 2GB) <code>InputStream</code> to an
1937         * <code>OutputStream</code>, optionally skipping input chars.
1938         * <p>
1939         * This method buffers the input internally, so there is no need to use a
1940         * <code>BufferedReader</code>.
1941         * <p>
1942         * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
1943         * 
1944         * @param input  the <code>Reader</code> to read from
1945         * @param output  the <code>Writer</code> to write to
1946         * @param inputOffset : number of chars to skip from input before copying
1947         *         -ve values are ignored
1948         * @param length : number of chars to copy. -ve means all
1949         * @return the number of chars copied
1950         * @throws NullPointerException if the input or output is null
1951         * @throws IOException if an I/O error occurs
1952         * @since 2.2
1953         */
1954        public static long copyLarge(Reader input, Writer output, final long inputOffset, final long length)
1955                throws IOException {
1956            return  copyLarge(input, output, inputOffset, length, new char[DEFAULT_BUFFER_SIZE]);
1957        }
1958    
1959        /**
1960         * Copy some or all chars from a large (over 2GB) <code>InputStream</code> to an
1961         * <code>OutputStream</code>, optionally skipping input chars.
1962         * <p>
1963         * This method uses the provided buffer, so there is no need to use a
1964         * <code>BufferedReader</code>.
1965         * <p>
1966         * 
1967         * @param input  the <code>Reader</code> to read from
1968         * @param output  the <code>Writer</code> to write to
1969         * @param inputOffset : number of chars to skip from input before copying
1970         *         -ve values are ignored
1971         * @param length : number of chars to copy. -ve means all
1972         * @param buffer the buffer to be used for the copy
1973         * @return the number of chars copied
1974         * @throws NullPointerException if the input or output is null
1975         * @throws IOException if an I/O error occurs
1976         * @since 2.2
1977         */
1978        public static long copyLarge(Reader input, Writer output, final long inputOffset, final long length, char [] buffer)
1979                throws IOException {
1980            if (inputOffset > 0) {
1981                skipFully(input, inputOffset);
1982            }
1983            if (length == 0) {
1984                return 0;
1985            }
1986            int bytesToRead = buffer.length;
1987            if (length > 0 && length < buffer.length) {
1988                bytesToRead = (int) length;
1989            }
1990            int read;
1991            long totalRead = 0;
1992            while (bytesToRead > 0 && EOF != (read = input.read(buffer, 0, bytesToRead))) {
1993                output.write(buffer, 0, read);
1994                totalRead += read;
1995                if (length > 0) { // only adjust length if not reading to the end
1996                    // Note the cast must work because buffer.length is an integer
1997                    bytesToRead = (int) Math.min(length - totalRead, buffer.length);
1998                }
1999            }
2000            return totalRead;
2001        }
2002    
2003        /**
2004         * Copy chars from a <code>Reader</code> to bytes on an
2005         * <code>OutputStream</code> using the default character encoding of the
2006         * platform, and calling flush.
2007         * <p>
2008         * This method buffers the input internally, so there is no need to use a
2009         * <code>BufferedReader</code>.
2010         * <p>
2011         * Due to the implementation of OutputStreamWriter, this method performs a
2012         * flush.
2013         * <p>
2014         * This method uses {@link OutputStreamWriter}.
2015         *
2016         * @param input  the <code>Reader</code> to read from
2017         * @param output  the <code>OutputStream</code> to write to
2018         * @throws NullPointerException if the input or output is null
2019         * @throws IOException if an I/O error occurs
2020         * @since 1.1
2021         */
2022        public static void copy(Reader input, OutputStream output)
2023                throws IOException {
2024            copy(input, output, Charset.defaultCharset());
2025        }
2026    
2027        /**
2028         * Copy chars from a <code>Reader</code> to bytes on an
2029         * <code>OutputStream</code> using the specified character encoding, and
2030         * calling flush.
2031         * <p>
2032         * This method buffers the input internally, so there is no need to use a
2033         * <code>BufferedReader</code>.
2034         * </p>
2035         * <p>
2036         * Due to the implementation of OutputStreamWriter, this method performs a
2037         * flush.
2038         * </p>
2039         * <p>
2040         * This method uses {@link OutputStreamWriter}.
2041         * </p>
2042         *
2043         * @param input  the <code>Reader</code> to read from
2044         * @param output  the <code>OutputStream</code> to write to
2045         * @param encoding  the encoding to use, null means platform default
2046         * @throws NullPointerException if the input or output is null
2047         * @throws IOException if an I/O error occurs
2048         * @since 2.3
2049         */
2050        public static void copy(Reader input, OutputStream output, Charset encoding) throws IOException {
2051            OutputStreamWriter out = new OutputStreamWriter(output, Charsets.toCharset(encoding));
2052            copy(input, out);
2053            // XXX Unless anyone is planning on rewriting OutputStreamWriter,
2054            // we have to flush here.
2055            out.flush();
2056        }
2057    
2058        /**
2059         * Copy chars from a <code>Reader</code> to bytes on an
2060         * <code>OutputStream</code> using the specified character encoding, and
2061         * calling flush.
2062         * <p>
2063         * This method buffers the input internally, so there is no need to use a
2064         * <code>BufferedReader</code>.
2065         * <p>
2066         * Character encoding names can be found at
2067         * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
2068         * <p>
2069         * Due to the implementation of OutputStreamWriter, this method performs a
2070         * flush.
2071         * <p>
2072         * This method uses {@link OutputStreamWriter}.
2073         *
2074         * @param input  the <code>Reader</code> to read from
2075         * @param output  the <code>OutputStream</code> to write to
2076         * @param encoding  the encoding to use, null means platform default
2077         * @throws NullPointerException if the input or output is null
2078         * @throws IOException if an I/O error occurs
2079         * @throws UnsupportedCharsetException
2080         *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
2081         *             supported.
2082         * @since 1.1
2083         */
2084        public static void copy(Reader input, OutputStream output, String encoding) throws IOException {
2085            copy(input, output, Charsets.toCharset(encoding));
2086        }
2087    
2088        // content equals
2089        //-----------------------------------------------------------------------
2090        /**
2091         * Compare the contents of two Streams to determine if they are equal or
2092         * not.
2093         * <p>
2094         * This method buffers the input internally using
2095         * <code>BufferedInputStream</code> if they are not already buffered.
2096         *
2097         * @param input1  the first stream
2098         * @param input2  the second stream
2099         * @return true if the content of the streams are equal or they both don't
2100         * exist, false otherwise
2101         * @throws NullPointerException if either input is null
2102         * @throws IOException if an I/O error occurs
2103         */
2104        public static boolean contentEquals(InputStream input1, InputStream input2)
2105                throws IOException {
2106            if (!(input1 instanceof BufferedInputStream)) {
2107                input1 = new BufferedInputStream(input1);
2108            }
2109            if (!(input2 instanceof BufferedInputStream)) {
2110                input2 = new BufferedInputStream(input2);
2111            }
2112    
2113            int ch = input1.read();
2114            while (EOF != ch) {
2115                int ch2 = input2.read();
2116                if (ch != ch2) {
2117                    return false;
2118                }
2119                ch = input1.read();
2120            }
2121    
2122            int ch2 = input2.read();
2123            return ch2 == EOF;
2124        }
2125    
2126        /**
2127         * Compare the contents of two Readers to determine if they are equal or
2128         * not.
2129         * <p>
2130         * This method buffers the input internally using
2131         * <code>BufferedReader</code> if they are not already buffered.
2132         *
2133         * @param input1  the first reader
2134         * @param input2  the second reader
2135         * @return true if the content of the readers are equal or they both don't
2136         * exist, false otherwise
2137         * @throws NullPointerException if either input is null
2138         * @throws IOException if an I/O error occurs
2139         * @since 1.1
2140         */
2141        public static boolean contentEquals(Reader input1, Reader input2)
2142                throws IOException {
2143            
2144            input1 = toBufferedReader(input1);
2145            input2 = toBufferedReader(input2);
2146    
2147            int ch = input1.read();
2148            while (EOF != ch) {
2149                int ch2 = input2.read();
2150                if (ch != ch2) {
2151                    return false;
2152                }
2153                ch = input1.read();
2154            }
2155    
2156            int ch2 = input2.read();
2157            return ch2 == EOF;
2158        }
2159    
2160        /**
2161         * Compare the contents of two Readers to determine if they are equal or
2162         * not, ignoring EOL characters.
2163         * <p>
2164         * This method buffers the input internally using
2165         * <code>BufferedReader</code> if they are not already buffered.
2166         *
2167         * @param input1  the first reader
2168         * @param input2  the second reader
2169         * @return true if the content of the readers are equal (ignoring EOL differences),  false otherwise
2170         * @throws NullPointerException if either input is null
2171         * @throws IOException if an I/O error occurs
2172         * @since 2.2
2173         */
2174        public static boolean contentEqualsIgnoreEOL(Reader input1, Reader input2)
2175                throws IOException {
2176            BufferedReader br1 = toBufferedReader(input1);
2177            BufferedReader br2 = toBufferedReader(input2);
2178    
2179            String line1 = br1.readLine();
2180            String line2 = br2.readLine();
2181            while (line1 != null && line2 != null && line1.equals(line2)) {
2182                line1 = br1.readLine();
2183                line2 = br2.readLine();
2184            }
2185            return line1 == null ? line2 == null ? true : false : line1.equals(line2);
2186        }
2187    
2188        /**
2189         * Skip bytes from an input byte stream.
2190         * This implementation guarantees that it will read as many bytes
2191         * as possible before giving up; this may not always be the case for
2192         * subclasses of {@link Reader}.
2193         *   
2194         * @param input byte stream to skip
2195         * @param toSkip number of bytes to skip.
2196         * @return number of bytes actually skipped.
2197         * 
2198         * @see InputStream#skip(long)
2199         * 
2200         * @throws IOException if there is a problem reading the file
2201         * @throws IllegalArgumentException if toSkip is negative
2202         * @since 2.0
2203         */
2204        public static long skip(InputStream input, long toSkip) throws IOException {
2205            if (toSkip < 0) {
2206                throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip);
2207            }
2208            /*
2209             * N.B. no need to synchronize this because: - we don't care if the buffer is created multiple times (the data
2210             * is ignored) - we always use the same size buffer, so if it it is recreated it will still be OK (if the buffer
2211             * size were variable, we would need to synch. to ensure some other thread did not create a smaller one)
2212             */
2213            if (SKIP_BYTE_BUFFER == null) {
2214                SKIP_BYTE_BUFFER = new byte[SKIP_BUFFER_SIZE];
2215            }
2216            long remain = toSkip;
2217            while (remain > 0) {
2218                long n = input.read(SKIP_BYTE_BUFFER, 0, (int) Math.min(remain, SKIP_BUFFER_SIZE));
2219                if (n < 0) { // EOF
2220                    break;
2221                }
2222                remain -= n;
2223            }
2224            return toSkip - remain;
2225        }
2226    
2227        /**
2228         * Skip characters from an input character stream.
2229         * This implementation guarantees that it will read as many characters
2230         * as possible before giving up; this may not always be the case for
2231         * subclasses of {@link Reader}.
2232         *   
2233         * @param input character stream to skip
2234         * @param toSkip number of characters to skip.
2235         * @return number of characters actually skipped.
2236         * 
2237         * @see Reader#skip(long)
2238         * 
2239         * @throws IOException if there is a problem reading the file
2240         * @throws IllegalArgumentException if toSkip is negative
2241         * @since 2.0
2242         */
2243        public static long skip(Reader input, long toSkip) throws IOException {
2244            if (toSkip < 0) {
2245                throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip);
2246            }
2247            /*
2248             * N.B. no need to synchronize this because: - we don't care if the buffer is created multiple times (the data
2249             * is ignored) - we always use the same size buffer, so if it it is recreated it will still be OK (if the buffer
2250             * size were variable, we would need to synch. to ensure some other thread did not create a smaller one)
2251             */
2252            if (SKIP_CHAR_BUFFER == null) {
2253                SKIP_CHAR_BUFFER = new char[SKIP_BUFFER_SIZE];
2254            }
2255            long remain = toSkip;
2256            while (remain > 0) {
2257                long n = input.read(SKIP_CHAR_BUFFER, 0, (int) Math.min(remain, SKIP_BUFFER_SIZE));
2258                if (n < 0) { // EOF
2259                    break;
2260                }
2261                remain -= n;
2262            }
2263            return toSkip - remain;
2264        }
2265    
2266        /**
2267         * Skip the requested number of bytes or fail if there are not enough left.
2268         * <p>
2269         * This allows for the possibility that {@link InputStream#skip(long)} may
2270         * not skip as many bytes as requested (most likely because of reaching EOF).
2271         * 
2272         * @param input stream to skip
2273         * @param toSkip the number of bytes to skip
2274         * @see InputStream#skip(long)
2275         * 
2276         * @throws IOException if there is a problem reading the file
2277         * @throws IllegalArgumentException if toSkip is negative
2278         * @throws EOFException if the number of bytes skipped was incorrect 
2279         * @since 2.0
2280         */
2281        public static void skipFully(InputStream input, long toSkip) throws IOException {
2282            if (toSkip < 0) {
2283                throw new IllegalArgumentException("Bytes to skip must not be negative: " + toSkip);
2284            }
2285            long skipped = skip(input, toSkip);
2286            if (skipped != toSkip) {
2287                throw new EOFException("Bytes to skip: " + toSkip + " actual: " + skipped);
2288            }
2289        }
2290    
2291        /**
2292         * Skip the requested number of characters or fail if there are not enough left.
2293         * <p>
2294         * This allows for the possibility that {@link Reader#skip(long)} may
2295         * not skip as many characters as requested (most likely because of reaching EOF).
2296         * 
2297         * @param input stream to skip
2298         * @param toSkip the number of characters to skip
2299         * @see Reader#skip(long)
2300         * 
2301         * @throws IOException if there is a problem reading the file
2302         * @throws IllegalArgumentException if toSkip is negative
2303         * @throws EOFException if the number of characters skipped was incorrect
2304         * @since 2.0
2305         */
2306        public static void skipFully(Reader input, long toSkip) throws IOException {
2307            long skipped = skip(input, toSkip);
2308            if (skipped != toSkip) {
2309                throw new EOFException("Chars to skip: " + toSkip + " actual: " + skipped);
2310            }
2311        }
2312        
2313    
2314        /**
2315         * Read characters from an input character stream.
2316         * This implementation guarantees that it will read as many characters
2317         * as possible before giving up; this may not always be the case for
2318         * subclasses of {@link Reader}.
2319         * 
2320         * @param input where to read input from
2321         * @param buffer destination
2322         * @param offset inital offset into buffer
2323         * @param length length to read, must be >= 0
2324         * @return actual length read; may be less than requested if EOF was reached
2325         * @throws IOException if a read error occurs
2326         * @since 2.2
2327         */
2328        public static int read(Reader input, char[] buffer, int offset, int length) throws IOException {
2329            if (length < 0) {
2330                throw new IllegalArgumentException("Length must not be negative: " + length);
2331            }
2332            int remaining = length;
2333            while (remaining > 0) {
2334                int location = length - remaining;
2335                int count = input.read(buffer, offset + location, remaining);
2336                if (EOF == count) { // EOF
2337                    break;
2338                }
2339                remaining -= count;
2340            }
2341            return length - remaining;
2342        }
2343    
2344        /**
2345         * Read characters from an input character stream.
2346         * This implementation guarantees that it will read as many characters
2347         * as possible before giving up; this may not always be the case for
2348         * subclasses of {@link Reader}.
2349         * 
2350         * @param input where to read input from
2351         * @param buffer destination
2352         * @return actual length read; may be less than requested if EOF was reached
2353         * @throws IOException if a read error occurs
2354         * @since 2.2
2355         */
2356        public static int read(Reader input, char[] buffer) throws IOException {
2357            return read(input, buffer, 0, buffer.length);
2358        }
2359    
2360        /**
2361         * Read bytes from an input stream.
2362         * This implementation guarantees that it will read as many bytes
2363         * as possible before giving up; this may not always be the case for
2364         * subclasses of {@link InputStream}.
2365         * 
2366         * @param input where to read input from
2367         * @param buffer destination
2368         * @param offset inital offset into buffer
2369         * @param length length to read, must be >= 0
2370         * @return actual length read; may be less than requested if EOF was reached
2371         * @throws IOException if a read error occurs
2372         * @since 2.2
2373         */
2374        public static int read(InputStream input, byte[] buffer, int offset, int length) throws IOException {
2375            if (length < 0) {
2376                throw new IllegalArgumentException("Length must not be negative: " + length);
2377            }
2378            int remaining = length;
2379            while (remaining > 0) {
2380                int location = length - remaining;
2381                int count = input.read(buffer, offset + location, remaining);
2382                if (EOF == count) { // EOF
2383                    break;
2384                }
2385                remaining -= count;
2386            }
2387            return length - remaining;
2388        }
2389        
2390        /**
2391         * Read bytes from an input stream.
2392         * This implementation guarantees that it will read as many bytes
2393         * as possible before giving up; this may not always be the case for
2394         * subclasses of {@link InputStream}.
2395         * 
2396         * @param input where to read input from
2397         * @param buffer destination
2398         * @return actual length read; may be less than requested if EOF was reached
2399         * @throws IOException if a read error occurs
2400         * @since 2.2
2401         */
2402        public static int read(InputStream input, byte[] buffer) throws IOException {
2403            return read(input, buffer, 0, buffer.length);
2404        }
2405    
2406        /**
2407         * Read the requested number of characters or fail if there are not enough left.
2408         * <p>
2409         * This allows for the possibility that {@link Reader#read(char[], int, int)} may
2410         * not read as many characters as requested (most likely because of reaching EOF).
2411         * 
2412         * @param input where to read input from
2413         * @param buffer destination
2414         * @param offset inital offset into buffer
2415         * @param length length to read, must be >= 0
2416         * 
2417         * @throws IOException if there is a problem reading the file
2418         * @throws IllegalArgumentException if length is negative
2419         * @throws EOFException if the number of characters read was incorrect
2420         * @since 2.2
2421         */
2422        public static void readFully(Reader input, char[] buffer, int offset, int length) throws IOException {
2423            int actual = read(input, buffer, offset, length);
2424            if (actual != length) {
2425                throw new EOFException("Length to read: " + length + " actual: " + actual);
2426            }
2427        }
2428    
2429        /**
2430         * Read the requested number of characters or fail if there are not enough left.
2431         * <p>
2432         * This allows for the possibility that {@link Reader#read(char[], int, int)} may
2433         * not read as many characters as requested (most likely because of reaching EOF).
2434         * 
2435         * @param input where to read input from
2436         * @param buffer destination
2437         * 
2438         * @throws IOException if there is a problem reading the file
2439         * @throws IllegalArgumentException if length is negative
2440         * @throws EOFException if the number of characters read was incorrect
2441         * @since 2.2
2442         */
2443        public static void readFully(Reader input, char[] buffer) throws IOException {
2444            readFully(input, buffer, 0, buffer.length);
2445        }
2446    
2447        /**
2448         * Read the requested number of bytes or fail if there are not enough left.
2449         * <p>
2450         * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may
2451         * not read as many bytes as requested (most likely because of reaching EOF).
2452         * 
2453         * @param input where to read input from
2454         * @param buffer destination
2455         * @param offset inital offset into buffer
2456         * @param length length to read, must be >= 0
2457         * 
2458         * @throws IOException if there is a problem reading the file
2459         * @throws IllegalArgumentException if length is negative
2460         * @throws EOFException if the number of bytes read was incorrect
2461         * @since 2.2
2462         */
2463        public static void readFully(InputStream input, byte[] buffer, int offset, int length) throws IOException {
2464            int actual = read(input, buffer, offset, length);
2465            if (actual != length) {
2466                throw new EOFException("Length to read: " + length + " actual: " + actual);
2467            }
2468        }
2469    
2470        /**
2471         * Read the requested number of bytes or fail if there are not enough left.
2472         * <p>
2473         * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may
2474         * not read as many bytes as requested (most likely because of reaching EOF).
2475         * 
2476         * @param input where to read input from
2477         * @param buffer destination
2478         * 
2479         * @throws IOException if there is a problem reading the file
2480         * @throws IllegalArgumentException if length is negative
2481         * @throws EOFException if the number of bytes read was incorrect
2482         * @since 2.2
2483         */
2484        public static void readFully(InputStream input, byte[] buffer) throws IOException {
2485            readFully(input, buffer, 0, buffer.length);
2486        }
2487    }